2017-03-07 12 views
1

我写了下面的代码,其中函数返回对成员的引用。在2个不同的函数调用期间,返回值以2种方式存储:是否从函数返回引用,导致在使用'auto'时创建新的临时对象?

  1. 自动引用用于存储返回值。正如我正确地假设,返回引用的对象的地址和存储返回值的自动引用的地址是相同的,从输出中可以看出。
  2. 'auto'用于存储返回值。我认为,auto变量应该导致在堆栈上创建一个新对象,该对象包含该函数返回引用的对象的值的副本。我可以看到自动和实际对象的地址确实不同。但是,我没有看到构造函数调用使用auto创建的对象。在这种情况下是否确实创建了一个对象?

//代码

#include <iostream> 
    using namespace std; 

    class c1 { 
    private: 
     int i; 

    public: 
     c1() { 
      cout << "c1()" << endl; 
      i = 10; 
     } 

    }; 

    class c2 { 
    private: 
     c1 mc1; 

    public: 
     c2() { 
      cout << "c2()" << endl; 
     } 

     c1& getmc1() { 
      cout << "address of mc1 : " << &mc1 << endl; 
      return mc1; 
     } 
    }; 

    int main() { 
     c2 c; 
     auto& c1_1 = c.getmc1(); 
     cout << "address of c1_1 : " << &c1_1 << endl; 

     c2 c_2; 
     auto c1_2 = c_2.getmc1(); 
     cout << "address of c1_1 : " << &c1_1 << endl; 

     return 0; 
    } 


//Output 
c1() 
c2() 
address of mc1 : 00AFF82C --> Same as below address, expected 
address of c1_1 : 00AFF82C 
c1() 
c2() 
address of mc1 : 00AFF814 --> Different from below address, expected 
address of c1_1 : 00AFF82C --> why c1() constructor is not invoked ? 

编辑

@NathanOliver,@Tali,

感谢您指出有关副本constrcutor。我加了一个,我可以看到正确的输出。我是C++的初学者。我错过了编译器生成隐式拷贝构造函数的观点。

以下是更新的程序。

#include <iostream> 
using namespace std; 

class c1 { 
private: 
    int i; 

public: 
    c1() { 
     cout << "c1()" << endl; 
     i = 10; 
    } 

    c1(c1 &c) { 
     cout << "c1(c1 &c)" << endl; 
     i = c.i; 
    } 

}; 

class c2 { 
private: 
    c1 mc1; 

public: 
    c2() { 
     cout << "c2()" << endl; 
    } 

    c1& getmc1() { 
     cout << "address of mc1 : " << &mc1 << endl; 
     return mc1; 
    } 
}; 

int main() { 
    // your code goes here 
    c2 c; 
    auto& c1_1 = c.getmc1(); 
    cout << "address of c1_1 : " << &c1_1 << endl; 

    c2 c_2; 
    auto c1_2 = c_2.getmc1(); 
    cout << "address of c1_1 : " << &c1_2 << endl; 

    return 0; 
} 

输出:

c1() 
c2() 
address of mc1 : 010FFE18 
address of c1_1 : 010FFE18 
c1() 
c2() 
address of mc1 : 010FFE00 
c1(c1 &c) 
address of c1_1 : 010FFDF4 
+0

你忘了复制构造函数。 – NathanOliver

+1

你的第二个案例的重复'cout << ...'有什么意义?你为'c1_2'获取一些东西,然后忽略它并再次输出'c1_1'的地址。 – WhozCraig

+0

@ WhozCraig, 谢谢指出。这是一个错字的经典案例:)。我在下面的帖子中修正了这个程序。添加一个复制构造函数解决了这个问题。 – codeseeker

回答

2

是新构造对象,但不使用你的c1::c1()。 这样的对象副本是使用复制构造函数c1::c1(const c1 &)完成的。

在您的示例中,您不提供复制构造函数,因此编译器将隐式生成一个。

相关问题