2012-10-14 118 views
0

下面的代码只打印A::A(),但没有A::A(const A&)operator=。为什么?为什么返回不复制对象?

struct A 
{ 
    A()    { cout << "A::A()" << endl; } 
    A(const A& value) { cout << "A::A(const A&)" << endl; } 

    A& operator=(const A& newValut) 
    { 
    cout << "A::operator=" << endl; 
    return *this; 
    } 
}; 

A foo() 
{ 
    A a;  //Ok, there we have to create local object by calling A::A(). 
    return a; //And there we need to copy it, otherwise it will be destroyed 
      //because it's local object. But we don't. 
} 

int main() 
{ 
    A aa = foo(); //Also there we need to put result to the aa 
        //by calling A::A(const A&), but we don't. 
} 

所以这个代码必须打印

A::A() 
A::A(const A&) 
A::A(const A&) 

但事实并非如此。为什么?

我建议没有内联foo()根据g++没有优化。

回答

3

这是一个复合型的C++做的如何返回:为返回的对象的位置实际上是由主叫方的调用函数的指针和指向这个尚未初始化对象作为隐藏参数传递之前提供到功能。该函数使用此内存位置从返回的表达式构造返回的对象。

因此,当返回的对象要直接初始化一个新对象,如程序A aa = foo();时,它不需要将返回值复制到堆栈上的对象。它要求函数直接在这个位置创建对象。所以最多只需要调用一次拷贝构造函数。 (事实上​​,如果您有2次调用复制构造函数,C++编译器将不符合)。现在

,最重要的是,编译器被允许优化掉在被称为“返回值优化”或RVO优化这一呼吁。这怎么可能?如果你看一下你的代码,你可以看到,你可以直接定义FOO()的返回值的拟议地点当地的“一个”变量,因此不必再次复制。这是一个重要的特性,因为拷贝构造函数可能很复杂并且运行速度很慢,所以在实现时(以及我知道的每个编译器都实现此功能),这可以显着提高性能。

所以你的情况,根据不同的编译器,你可能有1或0调用拷贝构造函数和你的编译器依然符合规定。

相关问题