【发布时间】:2017-03-07 17:13:46
【问题描述】:
我编写了以下代码,其中函数返回对成员的引用。在对函数的 2 次不同调用期间,返回值以 2 种方式存储:
- 自动引用用于存储返回值。正如我正确假设的那样,返回引用的对象的地址和存储返回值的自动引用的地址是相同的,从输出中可以明显看出。
- '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,
感谢您指出有关复制构造器的问题。我添加了一个,我可以看到正确的输出。我是 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
【问题讨论】:
-
你忘记了复制构造函数。
-
第二个案例中重复的
cout << ...有什么意义?你抢了c1_2的东西,然后忽略它,再次输出c1_1的地址。 -
@ WhozCraig,感谢您的指出。这是一个典型的错字案例:)。我在下面的帖子中更正了程序。添加复制构造函数解决了这个问题。