C++ C++;复制构造函数奇点

C++ C++;复制构造函数奇点,c++,copy-constructor,C++,Copy Constructor,我不明白为什么在下一段代码中,定义的复制构造函数不打印 #include <iostream> using namespace std; class B { static int count; int data; int id; void print(const char* p) { cout <<p <<", "<<id <<", " << data << end

我不明白为什么在下一段代码中,定义的复制构造函数不打印

#include <iostream>
using namespace std;
class B {
   static int count;
   int data; 
   int id;

   void print(const char* p)
   {
       cout <<p <<", "<<id <<", " << data << endl;
   }

   public:

   B(int d=0)
   {
      data=d; id=++count; print("B(int)");
   }
   B( const B& a)
   {
      data=a.data; id=++count; print("B(cost B&)");
   }
  ~B(){print("~B()");}

   operator bool(){ return (bool)data;}
   B operator+(int i){print("operator+"); return B(data+i);}
};


int B::count=0;

void main(){
   B b(42);
   B x=b+2;
   bool z=b+1;

   getchar();
}

那么这就是返回值优化了吗?

我很快就把它放到了GCC中,并注意到了同样的行为。显然,编译器正在以其认为合适的方式更改代码的行为

第一:赋值不等于复制构造函数。我想,因为它使用的是“=”,所以它在寻找运算符=重载,但没有找到它,然后选择使用常规构造函数创建一个新的B对象,然后使用默认赋值将其复制到x中。这是因为它是一个简单的类

我变了

B x=b+2;

试图强制它使用复制构造函数。但是我也有同样的行为。然后我查看了操作符+的返回类型,发现它返回了一个B(不是引用,但只要它遵守C++11之前的引用规则,就可以作为引用进行计算)。同样,编译器生成代码的方式与上面相同,因此我们没有使用复制构造函数

如果你改变

B x(b+2);

编译器计算出可以使用复制构造函数(即它能够生成对b的引用)

我猜想编译器生成代码是因为运算符+的返回类型。这可能与非常量引用仅在C++11之前的版本中作为左值处理有关。因此,由于运算符+正在被调用,它无法从中创建常量引用以传递到复制构造函数(因为运算符+的结果是左值)。因此,它使用常规构造函数和自动生成的赋值运算符来完成您请求的工作


希望这能有所帮助。

它可能被省略了。请参阅。@TheForestandeTrees没有任何东西可以移动。@OmniPotential复制省略不遵守“仿佛”规则。此外,
void main
不是合法签名。使用
int main
B x(b+2);
B x(b+2);
B x(b);