从函数返回引用是否会导致在使用'auto'时创建新的临时对象?
Does returning a reference from a function, result in creation of a new temporary object when 'auto' is used?
我编写了以下代码,其中函数返回对成员的引用。返回值在两个不同的调用函数时以两种方式存储:
- 使用自动参考来存储返回值。正如我正确地假设的那样,返回引用的对象的地址以及存储返回值的自动参考的地址是相同的,从输出中可以明显看出。
- '自动'用于存储返回值。我认为,自动变量应导致在堆栈上创建的新对象,其中包含函数返回引用的对象值的副本。我可以看到自动和实际对象的地址确实不同。但是,我没有看到构造函数被召唤使用使用自动创建的对象。在这种情况下确实创建了一个对象吗?
//代码
#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 ?
edit
@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
是的,是构造了新对象,但不使用您的c1::c1()
。此类对象的副本是使用复制构造函数c1::c1(const c1 &)
进行的。
在您的示例中,您不提供复制构造函数,因此编译器将隐式生成一个。
相关文章:
- 在不复制临时对象的情况下延长其生存期
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- 返回对临时对象的引用
- 防止临时对象文件访问 MSVC 中的磁盘
- 是否可以在C++中移动临时对象的属性?
- 通过引用传递临时对象
- 临时C++对象是否为左值?
- 临时对象:术语澄清
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 临时对象有身份吗?
- 临时对象上的运算符重载
- 如何在没有 std::move 的情况下移动临时对象
- 临时对象在C++中是不可避免的吗?
- 编译错误:临时对象构造函数中缺少参数
- 为什么在按值返回时创建临时对象,而不是在按值传递给函数参数时创建临时对象
- 我试图创建临时对象的方式有错误吗
- 子表达式中临时对象的生存期
- 对临时对象的Const引用不会延长其生存期
- 从函数返回引用是否会导致在使用'auto'时创建新的临时对象?