Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18688965
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: C/C++

2008-05-30 22:40:34

一、     什么是浅复制
    我想用一种形象的说法来说明这个问题。这里我的定义是不够严谨的,只是适合于C++的初学者。
   首先明确在C++中复制这个动作在内存中做了些什么?它先得到一个内存区域,然后再把要复制的东西“填进”这个区域。而所谓的“浅复制”并不是这样进行复制的,它仅仅是让一个指针指向要复制的区域。
 
二、     一个关于浅复制的简单例子
这里定义了Inner和Outter两个类。
 class Inner
{
      public:
            Inner();
            ~Inner();
      public:
           int min1;
};
 
class Outter
{
      public:
            Outter(int m_1);//让pInner->min1等于min1
            ~Outter();
      public:
            Inner* pInner;
};
Outter::~Outter()
{
      cout<<\"called the Destructors of Outter.\"<      delete pInner;
}
其它方法的实现很简单,这里就不写出来了。代码贴在最后面。下面有个问题,如果在一个函数(如main)中我们写了这几行代码,有会什么结果?
void print(Outter mOutter);
int main()
{
     Outter mOut1(20);
   print(mOut1);   
cout<min1< 
    return 0;
}
         print函数并不在那两个类中,它的实现如下:
void print(Outter mOutter)
{
      cout<<\"called print().\"<      cout<min1<}
      结果是,print函数结果正常,也就是20。但是,在main打印出的原来那个对象(mOut1)的min1值却变了,成了一个很小的负数,程序也出现异常了。如果去掉print(mOut1)这一行,结果也是20。那么问题就一定是出在print函数中了。可是我们用什么方法传递参数呢?我们是按“值传递”啊!按“理”说,出了这个函数后mOut1.pInner->min1的数据应该不会改变才对,可是事实它就是变了。
“值传递”在这里会为目标对象生成源对象的一个副本,更直接地说就是在内存会分配一个空间,将mOut1的数据复制进来。我们没定义复制构造函数,这时C++编绎器会为我们自动生成一个。但是很不幸,复制的工作没有做“深”,只是表面在让mOutter.pInner = mOut1.pInner,而不是让mOutter.pInner指向一个新开的区域,然后再往里面填相关的数据。所以当mOutter出作用域时,它会自动调用Outter的析构函数。由于我们在析构函数里用了delete pInner(想想为什么要用这个),它当然把所指的内存区域释放掉。所以,在print后我们用cout<min1<三、     问题的解决
  前面我们分析了问题的根源,现在想想应该怎么解决这个问题?这个问题的解决比查出它的原因容易得多。我们只需把没有做“深”的事情做“深”就可以了。既然C++编程器的复制构造函数“不好用”,我们就自己写一个吧。代码如下:
Outter::Outter(const Outter& mOut)
{
    cout<<\"called the Copy Constructors of Outter.\"<      pInner = new Inner();//重新分配一个区域,把工作做“深”
      pInner->min1 = mOut.pInner->min1; 
}
加上const是保证mOut的数据在这个函数中不会被修改。
 
 
下面把代码贴上,在VC++6.0中能正常运行,其它编绎器我没试过。
#include 
 
using namespace std;
 
class Inner
{
    public:
          Inner();
          ~Inner();
    public:
          int min1;
 
};
 
Inner::Inner()
{
    cout<<\"called the Constructors of Inner.\"<}
 
Inner::~Inner()
{
    cout<<\"called the Destructors of Inner.\"<}
 
 
class Outter
{
    public:
          Outter(int m_1);
          Outter(const Outter& mOut);

[NextPage]


          ~Outter();
    public:
          Inner* pInner;
};
 
Outter::Outter(int m_1)
{
    cout<<\"called the Constructors of Outter.\"<    pInner = new Inner;
    pInner->min1 = m_1;
}
 
Outter::Outter(const Outter& mOut)
{
    cout<<\"called the Copy Constructors of Outter.\"<    pInner = new Inner();
    pInner->min1 = mOut.pInner->min1;
}
 
Outter::~Outter()
{
    cout<<\"called the Destructors of Outter.\"<    delete pInner;
}
 
 
void print(Outter mOutter)
{
    cout<<\"called print().\"<    cout<min1<}
 
int main()
{
    Outter mOut1(20);
 
    print(mOut1);
    cout<min1<    return 0;
}

阅读(680) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~