C++ 空字符串构造函数
Posted
技术标签:
【中文标题】C++ 空字符串构造函数【英文标题】:C++ empty String constructor 【发布时间】:2009-05-29 11:18:22 【问题描述】:我是 C++ 初学者,如果问题太基本,请见谅。
我已经尝试收集字符串 constrcturs 并尝试所有它们(以记住它们)。
string strA(); // string(); empty string // incorrect
string strB("Hello"); // string( const char* str)
string strC("Hello",3); // string( const char* str, size_type length)
string strD(2,'c'); // string( size_type lenght, const char &c)
string strE(strB); // string( const string& s)
cout << strA << endl;
cout << strB << endl;
cout << strC << endl;
cout << strD << endl;
cout << strE << endl;
除了 strA 之外,所有这些都有效。它打印“1”。 为什么?在这种情况下 strA 的类型是什么?当我不确定时如何检查物品的类型?
我注意到正确的方法是这样(顺便说一句,这似乎与其他构造函数不一致,有时parens有时没有parens):
string strA;
ps:粗体问题,通常不相关的答案将被否决。
【问题讨论】:
【参考方案1】:这是一个非常受欢迎的问题。 C++ 语法是模棱两可的。解决歧义的规则之一是“如果某件事看起来像声明,那就是声明”。在这种情况下,您声明了一个函数原型,而不是定义一个变量。
string strA();
等价于
string strA(void);
返回字符串的无参数函数原型。
如果你想显式调用无参数构造函数,试试这个:
string strA=string();
它并不完全等价——它的意思是“使用无参数构造函数创建一个临时字符串,然后将其复制以初始化变量 strA”,但允许编译器对其进行优化并省略复制。
编辑: Here is an appropriate item in C++ FAQ Lite
【讨论】:
这也是我停止使用 C++ 的原因之一。 @Dietrich Epp:这也困扰着我。我想这是为保持 C 兼容性而付出的代价。另一种选择是使用 C,它有很多问题,我的猜测是最好保留 C++ 并避免这种陷阱。std::string strA("");
怎么样【参考方案2】:
它认为
string strA();
作为函数声明。
对于默认构造函数使用:
string strA;
【讨论】:
在堆外分配时可以使用该符号:string* strA = new string();【参考方案3】:在 C++ 中,就像在 C 中一样,有一条规则规定任何看起来像声明的东西都将被视为声明。
string strA();
看起来像一个函数声明,所以它被视为一个。你需要:
string strA;
【讨论】:
【参考方案4】:我认为在这种情况下,“如果可以是声明,则视为声明”的规则不适用。因为在下文中,两者都是声明
string a;
string a();
一个是对象的声明,一个是函数的声明。该规则适用于其他情况。例如,在这种情况下:
string a(string());
在这种情况下,string()
可能意味着两件事。
string
的表达式
这里也适用,string()
的意思和下面的一样,命名参数(在声明函数时,名称与参数无关)
string a(string im_not_relevant());
如果函数将数组或另一个函数作为参数,则该参数会衰减为指针。在函数参数的情况下,指向函数的指针。因此,它等价于以下,可能看起来更熟悉
string a(string (*im_not_relevant)());
但在你的情况下,它是进入方式的语法。就是说下面是一个函数声明。它永远不能是一个对象的声明(即使这可能是程序员的意图!)
string a();
所以首先在这个上下文中没有歧义,因此它声明了一个函数。由于string
有一个用户定义的构造函数,您可以省略括号,效果与预期相同。
【讨论】:
【参考方案5】:它打印1
,因为指向函数的指针总是转换为数字,如@987654322@。
【讨论】:
仅当指向函数的指针不为空时。无论如何,指向函数的指针应该指向它的定义,而这里没有。这不应该链接。【参考方案6】:tkopec 关于它为什么不起作用的原因是正确的。要回答您的第二个问题,请按以下方式检查类型:
template<typename TEST> void Error_()
TEST* MakeError = 1;
调用Error_(StrA);
你会得到一个编译错误,你的编译器可能会告诉你它发生在Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void))
现在,std::basic_string > 只是 std::string,所以这真的意味着Error_< std::string (*)(void)> (std::string (*)(void))
。 '' 之间的部分在'()' 之间重复,这就是strA 的类型。在这种情况下,std::string (*)(void)
。
【讨论】:
strA 的类型是一个函数。 std::string(void) 。它不是函数指针。他必须将其声明为字符串 (*strA)();如果他希望它是一个函数指针。我可能知道你的意思,但你的最后几句话听起来像你说的是一个函数指针。【参考方案7】:编译器将string strA()
解释为函数的函数原型,该函数接受void 参数并返回字符串类型的对象。如果要创建一个空字符串对象,请使用string strA;
(不带括号)
【讨论】:
以上是关于C++ 空字符串构造函数的主要内容,如果未能解决你的问题,请参考以下文章
串练习之Example008-构造串的链表结点数据结构(每个结点内存储一个字符),编写一个函数,找出串 `str1` 中第一个不在串 `str2` 中出现的字符