2013-07-01 26 views
6

我只是创造了这样一个类:关于构造函数和指定运营商在C++

class GreatClass 
{ 
public: 
    GreatClass(){cout<<"Default Constructor Called!\n";} 
    GreatClass(GreatClass &gc){cout<<"Copy Constructor Called!\n";} 
    GreatClass(const GreatClass &gc){cout<<"Copy Constructor (CONST) Called!\n";} 
    ~GreatClass(){cout<<"Destructor Called.\n";} 
    GreatClass& operator=(GreatClass& gc){cout<<"Assign Operator Called!";return gc;} 
    const GreatClass& operator=(const GreatClass& gc){cout<<"Assign Operator (CONST) Called!";return gc;} 
}; 

GreatClass f(GreatClass gc) 
{ 
    return gc; 
} 

,并在main()函数,有两个版本:

版本#1:

int main() 
{ 
    GreatClass g1; 
    GreatClass G = f(g1); 
} 

版本#2:

int main() 
{ 
    GreatClass g1; 
    f(g1); 
} 

他们所有产生相同的输出:

Default Constructor Called! 
Copy Constructor Called! 
Copy Constructor Called! 
Destructor Called. 
Destructor Called. 
Destructor Called. 

我不明白,为什么没有什么,当我分配到f(g1)发生G。此时调用的构造函数或操作符是什么?

谢谢。

+4

复制elision是怎么回事。如果您使用的是GCC,请尝试使用'-fno-elide-constructors'编译标志。 –

+0

我想可能是你的困惑的一部分原因是'operator ='没有被使用。这是由标准决定的。形式为'A a2 = a1;'的东西是复制初始化,并且使用了复制构造函数(而不是赋值运算符)。复制elision也可以发挥作用。 – huskerchad

回答

13

编译器实现允许在某些情况下删除/删除拷贝构造函数调用,您指定的示例是这种情况的一个很好的示例用例。不是创建一个临时对象,然后将其复制到目标对象,而是直接在目标对象中创建对象,并将复制构造函数调用移除。

这种优化是通过Return value optimization称为复制省略

此外,与C++ 11 move semantics through rvalue references可能会踢,而不是复制语义。即使有移动语义,编译器仍然可以自由应用RVO。