我知道这个程序出了错,我想知道的是为什么出了错?
#include <iostream>
using namespace std;
class A
{
public:
A(int i){cout < < "执行构造函数创建一个对象\n ";x=i;}
A(const A&i){cout < < "执行复制构造函数创建一个对象\n ";}
~A(){cout < < "执行析构函数!\n ";}
int get(){return x;}
private:
int x;
};
A func();
int main()
{
A&r=func();//r作为*p的别名
cout < <&r < <endl;//r的地址就是返回的p中保存的对象的地址。
//换句话说,r的地址就是使用*读取的p地址处保存的数据,
//也就是堆中对象的内存地址。
cout < <r.get() < <endl;//使用r来访问get()函数相当于使用
//指针*p访问get()函数,由于r是直接访问,所以不用
//加间接引用运算符-> ,用点运算符(.)即可。
A*pa=&r;//将指针p赋给pa
delete pa;//删除指针pa指向的空间后,r又做谁的别名?
return 0;
}
A func()
{
A *p=new A(99);//创建一个堆中对象并用p指向它同时初始化
//该对象的成员变量x的值为99
cout < < "p: " < <p < <endl;//输出p中保存的值。
cout < < "&p: " < <&p < <endl;//输出p的地址。
return *p;
}
输出:
执行构造函数创建一个对象
p:00031148
执行复制构造函数创建一个对象
0013FF6C
-858993460
执行析构函数
我知道这个程序出了错,我想知道的是为什么出了错,我也知道返回的是*p的副本,但是我想知道返回的是堆中对象的拷贝还是*p的拷贝,第一个对象被析构了,它是如何被析构的,毕竟该对象是在堆中创建的匿名对象,除非指针p来删除它,否则无法对其进行释放,另外我还想知道r作为返回的*p的副本的别名,为何再次输出r也就是p中保存的地址,它居然变化了,是什么让它变化的??
[解决办法]
1.为什么r所引用的临时对象的地址改变了?
r所引用的临时对象是func()中*p的副本(换句话说,r与*p是两个不同的对象,只不过r的内容是从*p中获取的),它当然不会与p的地址一样了.而且,正如你知道的那样,r在栈中,而*p在堆中.
2. 为什么r所引用的临时对象的成员变量x的值也没了?
因为你的copy consturctor没有给赋值, 如下这样就可以了.
A(const A&i){x=i.x; cout < < "执行复制构造函数创建一个对象\n ";}
btw, 你的 "delete pa "一句有问题.pa指向的是栈对象,不能delete