引用与';重新声明 我在使用C++代码时曾多次看到以下类型错误: QString str = str.toUpper();

引用与';重新声明 我在使用C++代码时曾多次看到以下类型错误: QString str = str.toUpper();,c++,construction,C++,Construction,这可能是一个相当容易犯的错误,但它编译并执行(有时有崩溃,有时没有)。我看不出在什么情况下你会真的想这么做 一些测试表明,复制构造函数是被调用的,而不是默认的,并且对象是从复制构造函数中给定的 有人能解释为什么这不是编译器错误,甚至不是警告吗?没有错误或警告,因为它相当于: QString str; str = str.toUpper(); 就像 QString str = "aaa"; 与 QString str; str = "aaa"; 要在同一语句中执行此操作,您需要使用构造函数,

这可能是一个相当容易犯的错误,但它编译并执行(有时有崩溃,有时没有)。我看不出在什么情况下你会真的想这么做

一些测试表明,复制构造函数是被调用的,而不是默认的,并且对象是从复制构造函数中给定的


有人能解释为什么这不是编译器错误,甚至不是警告吗?

没有错误或警告,因为它相当于:

QString str;
str = str.toUpper();
就像

QString str = "aaa";

QString str;
str = "aaa";
要在同一语句中执行此操作,您需要使用构造函数,它不会编译:

QString str(str.toUpper());
就像:

QString str("aaa");
不等于

QString str;
str = "aaa";

从技术上讲,对象
str
是在到达等号时定义的,因此可以在该点使用

错误发生在试图用对象本身初始化对象时,允许编译器对此发出警告(如果它能够检测到)。但是,由于并非所有情况下都可以检测,因此不需要编译器


例如
intx=f(x)intf(const int&)
不使用其参数值,则code>是完全正确的。如果编译器还没有看到函数体,怎么知道呢?

这被指定为未定义的行为(不需要诊断),可能是因为这类代码的一个或多个实例的诊断过于复杂。可能是因为编译器不知道toUpper()返回相同的实例?我可以想象编译器编写人员很难检查它。@MarkB:这是定义的行为,请参见我的答案。它绝对不等同于
QString str;str=str.toUpper()就像
QString str=“aaa”
不调用赋值运算符。Are
QString str=“aaa”
QString str;std=“aaa”
实际上是一样的吗?我不是C++专家,但对我来说,第一个调用构造函数,第二个调用默认构造函数,然后是代码>运算符=< /COD>。似乎同意。-1:
QString str=“aaa”
不会调用默认构造函数。它将调用接受
常量char*
的构造函数,该构造函数的参数将是
“aaa”
。也就是说,它不同于默认构造
QString
,然后对其进行复制赋值。@Nicolas:它还将调用复制构造函数。该调用可以省略,但是,语法QString str=“aaa”需要一个可访问的副本构造函数,而不管实际调用是否被省略,这是有意义的。我想我会争辩(为了理智起见,如果没有其他原因的话)在尚未构造的x上调用f(x)仍然应该是一个错误,因为正如你提到的,唯一安全的情况是函数不使用它。啊,是的,但函数可以写入它,对于内置类型,这实际上是可以的。值得注意的是,当通过
auto
关键字定义对象时,这种语法是特别禁止的,但出于类型推断的原因<代码>自动x=x+1无效,兼容的编译器应该拒绝它。@Chris-它实际上可以保存一个指向该对象的指针或引用,并在以后使用它。”。它只是不能使用该值(因为还没有)。C和C++是已知的,它不禁止仅仅是远程有用的东西。那么,在等式符号中,<代码> x <代码>的状态究竟是什么?此时调用了哪个构造函数?