首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

小弟我知道这个程序出了错,小弟我想知道的是为什么出了错

2012-03-20 
我知道这个程序出了错,我想知道的是为什么出了错?#includeiostreamusingnamespacestdclassA{public:A(i

我知道这个程序出了错,我想知道的是为什么出了错?
#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

热点排行