我正在测试的这个程序的结果对我来说没有意义:
class CC {
public:
int a;
CC();
CC(int a);
~CC();
};
CC::CC() {
this->a = 0;
}
CC::CC(int a) {
this->a = a;
}
CC::~CC() {
}
const CC f() {
CC cc(2);
cout << &cc << endl;
return cc;
}
int main() {
CC cc = f();
cc.a = 3;
cout << &cc << " " << cc.a << endl;
}
result: // note the address are the same
0x7ffdd24b26e0
0x7ffdd24b26e0 3
我不明白为什么我可以在main()中使用非const变量来接收const返回值函数?内存地址是相同的,因此两个局部变量应该指向同一个对象。
g ++版本:
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
答案 0 :(得分:7)
为什么我可以在main()中使用非const变量来接收const返回值函数?
因为函数的返回值被复制到变量cc
中。制作const
对象的非const
副本没有错;它不允许您修改const
对象。
请将您想知道的任何其他内容重新发布为单独的问题。
答案 1 :(得分:0)
如果您无法在=
的右侧使用常量,那么CC.a = 3;
将是非法的。那将是疯狂的。使用常量的值肯定是合法的 - 你还会用常数做什么?
至于返回堆栈值,您将返回值。 return
执行时,该值已明确定义。该对象后来不再存在并不重要,因为您已经返回了它的值。
int foo()
{
int i = 3;
return i;
}
在这里,我们返回i
的值,即返回3.没有错。
int& foo()
{
int i = 3;
return i;
}
这里我们返回对i
的引用。但i
已不复存在。那不好。
答案 2 :(得分:0)
FWIW,const CC
的返回值与CC
相同。
假设:
struct CC {};
const CC f() {
return {};
}
g ++ 4.9.3生成的汇编代码与为:
生成的汇编代码完全相同struct CC {};
CC f() {
return {};
}
<强> PS 强>
这可能是标准中我无法快速找到的地方。
答案 3 :(得分:0)
参考:Why function in c++ can return stack values
两个地址相同的原因是因为RVO。从语义上讲,main()中的变量'cc'仍然是f()中局部变量的副本。因为它只是原始对象的副本,所以将const返回值赋给非const变量是有意义的。