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,因为指向函数的指针总是转换为数字,如@9​​87654322@。

【讨论】:

仅当指向函数的指针不为空时。无论如何,指向函数的指针应该指向它的定义,而这里没有。这不应该链接。【参考方案6】:

tkopec 关于它为什么不起作用的原因是正确的。要回答您的第二个问题,请按以下方式检查类型:

template<typename TEST> void Error_() 
   TEST* MakeError = 1;

调用Error_(StrA);你会得到一个编译错误,你的编译器可能会告诉你它发生在Error_&lt; std::basic_string&lt;char, std::allocator&lt;char&gt; &gt; (*)(void)&gt;(std::basic_string&lt;char, std::allocator&lt;char&gt; &gt; (*)(void)) 现在,std::basic_string > 只是 std::string,所以这真的意味着Error_&lt; std::string (*)(void)&gt; (std::string (*)(void))。 '' 之间的部分在'()' 之间重复,这就是strA 的类型。在这种情况下,std::string (*)(void)

【讨论】:

strA 的类型是一个函数。 std::string(void) 。它不是函数指针。他必须将其声明为字符串 (*strA)();如果他希望它是一个函数指针。我可能知道你的意思,但你的最后几句话听起来像你说的是一个函数指针。【参考方案7】:

编译器将string strA() 解释为函数的函数原型,该函数接受void 参数并返回字符串类型的对象。如果要创建一个空字符串对象,请使用string strA;(不带括号)

【讨论】:

以上是关于C++ 空字符串构造函数的主要内容,如果未能解决你的问题,请参考以下文章

C++——string类

C++中的string详解

c++ string类的常用方法

传递给类构造函数的 C++ 字符串 - 链接器错误

串练习之Example008-构造串的链表结点数据结构(每个结点内存储一个字符),编写一个函数,找出串 `str1` 中第一个不在串 `str2` 中出现的字符

java中String类的构造函数