在处理C++代码时,我几次看到了以下类型错误:
QString str = str.toUpper();
这是一个相当容易犯的错误,但它仍然可以编译和执行(有时会崩溃,有时不会)。我无法想象在任何情况下,这都是你实际想要做的事情。
一些测试表明,调用的是复制构造函数而不是默认构造函数,并且对象正在从复制构造函数内部被赋予自身。
是否有人能够解释为什么这不是编译器错误,甚至不是警告?
在处理C++代码时,我几次看到了以下类型错误:
QString str = str.toUpper();
这是一个相当容易犯的错误,但它仍然可以编译和执行(有时会崩溃,有时不会)。我无法想象在任何情况下,这都是你实际想要做的事情。
一些测试表明,调用的是复制构造函数而不是默认构造函数,并且对象正在从复制构造函数内部被赋予自身。
是否有人能够解释为什么这不是编译器错误,甚至不是警告?
在等号出现时,对象str
已经被定义,因此可以在该点使用。
错误在于试图用自身初始化对象,编译器允许警告(如果它能够检测到)。然而,在每种情况下都无法进行检测,因此编译器不是必需的。
例如,如果int f(const int&)
不使用其参数的值,则int x = f(x);
是完全正确的。如果编译器尚未看到函数体,它如何知道呢?
x
的状态到底是什么?哪个构造函数在那时被调用了? - Kerrek SBthis
传递给基类构造函数……它看起来不同,但最终结果是相同的。 - Dennis Zickefoose没有错误或警告,因为它等同于:
QString str;
str = str.toUpper();
就像这样
QString str = "aaa";
等同于
QString str;
str = "aaa";
要在同一语句中完成这个操作,你需要使用构造函数,但这样做是无法编译通过的:
QString str(str.toUpper());
就像这样:
QString str("aaa");
不等于
QString str;
str = "aaa";
QString str; str = str.toUpper();
和 QString str = "aaa";
并不等同,就像后者并没有调用赋值运算符一样。” - Mark BQString str = "aaa";
和 QString str; std = "aaa"
实际上是一样的吗?我不是 C++ 专家,但在我看来,第一个调用了构造函数,而第二个则调用了默认构造函数和 operator=
。Codepad 似乎也是这么认为的。 - user395760QString str = "aaa"
不会调用默认构造函数。它将调用一个接受 const char*
的构造函数,而该构造函数的参数将是 "aaa"
。也就是说,这与默认构造 QString
然后进行复制赋值不同。 - Nicol Bolas