2016-11-20 75 views
0

我知道表达式像MyClass a = b是一个复制初始化,它会调用复制构造函数。表达式MyClass a = b + c是一个拷贝初始化吗?

MyClass a = b + c呢?

我试过了。在Visual Studio 2015中,似乎表达式不是复制初始化,也不是复制任务。所以它是什么?

下面是我测试的代码:

class MyClass 
{ 
public: 
    MyClass() 
    { 
     cout << "default constructor has been called!" << endl; 
    } 
    MyClass(const MyClass& cls) 
    { 
     cout << "copy constructor has been called!" << endl; 
    } 
    MyClass operator+(const MyClass& cls) const 
    { 
     cout << "operator + has been called!" << endl; 
     return MyClass(); 
    } 
    MyClass& operator=(const MyClass& cls) 
    { 
     cout << "operator = has been called!" << endl; 
     return *this; 
    } 
}; 

int main() 
{ 
    MyClass b, c; 
    MyClass a = b + c; 
    return 0; 
} 

并且输出是

default constructor has been called! 
default constructor has been called! 
operator + has been called! 
default constructor has been called! 
+0

'MyClass&operator =(const MyClass&cls)' - 此函数调用未定义的行为,因为您未能返回值。 – PaulMcKenzie

+0

对不起,我的错误。我纠正了它。但我认为这个问题不是严重的误导。 – AK2806

+0

它是严重的,它在程序的工作方式中扮演着重要角色。没有回报价值,任何事情都可能发生。 – PaulMcKenzie

回答

0

你体验被称为返回值优化什么(见What are copy elision and return value optimization?):

这是在这里的第一个例子描述。

编译器优化代码(以最小化创建的对象),并使得a实际上是您的+运算符声明并返回的本地对象。然后,没有使用复制构造函数。这是你在这里观察到的。

很好地观察到这一点,改变你的代码,看看对象的内存不会忽略:

#include <iostream> 
using namespace std; 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     cout << "default constructor has been called for " << std::hex << this << endl; 
    } 
    MyClass(const MyClass& cls) 
    { 
     cout << "copy constructor has been called for " << std::hex << this << " (copied from " << &cls << ")" << endl; 
    } 
    MyClass operator+(const MyClass& cls) const 
    { 
     cout << "operator + has been called!" << endl; 
     MyClass res; 
     cout << "operator + returns temporary object " << std::hex << &res << endl; 
     return res; 
    } 
    MyClass& operator=(const MyClass& cls) 
    { 
     cout << "operator = has been called!" << endl; 
     return *this; 
    } 
}; 

int main() 
{ 
    MyClass b, c; 
    MyClass a = b + c; 
    cout << "a object is " << std::hex << &a << endl; 
    return 0; 
} 

它输出:

default constructor has been called for 0x7ffd44b769fd 
default constructor has been called for 0x7ffd44b769fe 
operator + has been called! 
default constructor has been called for 0x7ffd44b769ff 
operator + returns temporary object 0x7ffd44b769ff 
a object is 0x7ffd44b769ff 

你看,在operator+创建的临时对象是一样的a0x7ffd44b769ff ),由于编译器的优化。

如果使用g ++,请使用-fno-elide-constructors进行编译以禁用此编译器优化。而现在输出的是:

default constructor has been called for 0x7ffd92847d1c 
default constructor has been called for 0x7ffd92847d1d 
operator + has been called! 
default constructor has been called for 0x7ffd92847cff 
operator + returns temporary object 0x7ffd92847cff 
copy constructor has been called for 0x7ffd92847d1f (copied from 0x7ffd92847cff) 
copy constructor has been called for 0x7ffd92847d1e (copied from 0x7ffd92847d1f) 
a object is 0x7ffd92847d1e 

你看,现在operator+创建一个本地对象(0x7ffd92847cff),这是后来复制的临时对象return语句(复制0x7ffd92847cff0x7ffd92847d1f),最后将其用于构建通过复制(复制0x7ffd92847d1f0x7ffd92847d1e)。

相关问题