C++ 为什么在声明对象时既不执行构造函数也不执行赋值运算符?
测试程序是C++ 为什么在声明对象时既不执行构造函数也不执行赋值运算符?,c++,oop,constructor,assignment-operator,C++,Oop,Constructor,Assignment Operator,测试程序是 #include <iostream> using namespace std; class A {public: A (): I(0) {cout << "default construcot" << endl; }; explicit A (int i): I(i) {cout << "another construcot" << endl; }; A (const A&
#include <iostream>
using namespace std;
class A
{public:
A (): I(0) {cout << "default construcot" << endl; };
explicit A (int i): I(i) {cout << "another construcot" << endl; };
A (const A& a): I(a.I) {cout << "copy constructor" << endl; }
A& operator = (const A& a)
{cout << "assignment operator" << endl;
if (this == &a) return *this;
I = a.I;
return *this;
}
void show () {cout << I << endl; };
private:
int I;
};
int main ()
{A a = A(1);
A b;
b = A(2);
a.show();
b.show();
return 0;
}
显示了与“b”不同的对象“a”是由a(1)“直接”构造而成,无需执行赋值运算符。但复制构造函数也没有执行。为什么?在这种情况下,有没有办法强制执行赋值运算符?如果我写信,我会预料到这种行为
A a (1);
但是我想要
A a = A(1);
与第一种情况不同。还是不
(事实上,当我有一个从a派生的类B,并且希望a的赋值操作符像a=B(…)一样处理声明时,问题就出现了。)为什么?因为编译器可以自由地这样做,而且大多数编译器都可以这样做 你能强迫它吗?否。此
A a = A(1);
不等同于此:
A a;
a = A(1);
在第二种情况下,
=
是运算符,在第一种情况下,=
不是运算符。在第一条语句中,它是一种初始化语法。编译器可以调用复制构造函数,但它可以对其进行优化,因为这是语言允许的地方之一(RVO、异常抛出等)。它在语言中明确定义,编译器基本上可以在任何时候删除复制构造,第一种形式是初始化语法。但是,当您使用实际的派生实例调用它时,您可能会发现此行为被删除,因为这样做会影响程序的正确性
为什么
该标准允许编译器优化复制构造。不是这是一个赋值,因为它是声明的一部分(因此,如果没有进行优化,它将生成一个临时对象,然后将临时对象的构造复制到一个新的对象中)
在这种情况下,是否有强制执行赋值运算符的方法
这将取决于您的编译器。但我不知道有哪一个能让你强制这样做(但我从未尝试过关闭它)。尝试关闭编译器正在进行的所有优化
如果我写下:A(1)
该标准明确规定,您的版本可以优化为该版本
我有一个从a派生的类B,并希望a的赋值运算符像a=B(…)一样处理声明。)
如果这样做,您将对B进行切片,并只分配B对象的A部分。您想使用参考资料吗
A const& a = B();
我希望
A(1)代码>和aa=1
严格来说是一样的,它是由标准保证的。编译器编写者足够聪明,不需要对赋值运算符/复制构造函数进行不必要的调用。如果(this==&a)
类如此简单以至于它无关紧要,为什么还要关心self的赋值呢。如果它更复杂,那么你应该使用复制和交换idium,然后测试就变得多余了。。。我可以使用引用,甚至指针,但是。。。让我们想想,有人会使用我的类,并期待它的“正常”行为。也许我正试图以错误的方式做每件事,也许我将来会征求意见。
A const& a = B();