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();