构造函数与拷贝解析

来源:互联网 发布:淘宝上买东西寄到美国 编辑:程序博客网 时间:2024/06/06 00:03
当我们声明一个类的时候,可能会需要另外一个类的实体去初始化一个新定义的类。
// 类定义
// 此类只能实现数据的拷贝,而不能够对资源进行操作。
class ScreenOnlyCopyData
{
public:
      
short height(){/* ... */}
      
short weight(){/* ... */}
      
string  screen(){/*...*/}

private:
     
string _screen;
     
string::size_type _cursor;
     
short   _height,_weight;
}
;
//当有一个类对象实现时,
        ScreenOnlyCopyData s1;
        
//对s1进行操作.....
      ScreenOnlyCopyData s2=s1;
     
//等同于下面的语句
        s2._screen = s1._screen;
        s2._cursor 
= s1._cursor;
        s2._height 
= s1._height;
        s2._weight 
= s1._weight;
//所以,当我们定义了一个带有资源分配的类类型时,在类之间相互拷贝必须重新构造拷贝构造函数,
// 否则将只对值进行简单的赋值过程,最终导致两个类对象指向同一个资源,在其中一个对象将
// 资源析构时,另一个对象原本指向资源的指针将指向一个未定义的资源,从而导致错误的发生。
// 具体见下面的代码,为使分析简单,仅使用两个成员。

Class NoResourceToCopy
{
public:
      NewResource(size_type len)
{*= new int [len];} 
      
~NoResourceToCopy(){delete []p;}
private:
       
int *p;
       
int s;
}
;

NoResourceToCopy nr1;
nr1.NewResource(
10);
NoResourceToCopy nr2
=nr1;               //特殊语句1
//按上面的解释,这特殊语句1应该等同于下面的语句的集合
// nr2.p=nr1.p;
// nr2.s=nr2.s;
// 所以,当nr1析构时,nr2中的p指向的内存块是不明确的,因此会出现错误。
// 因此为使特殊语句1能够成功获取资源,需要如下的定义。

Class RecourseToCopy
{
public:
    RecourseToCopy()
{}
    ResourceToCopy( ResourceToCopy 
& )
   
{}
   
~RecourseToCopy(){}
private:
    
int *p;
    
int len;
}
;

RecourseToCopy::ResouceToCopy()
{
    
*=NULL:
   len
= 0;
}


ResourceToCopy::ResourceToCopy(ResourceToCopy 
&s)
{
   
if(NULL == s.p)
    
{      
        
this->p=NULL;
        
this->len=0;
   }

   
this->p=new int[s1.len];   //只有在此处再次申请资源,才能保证s1被解析时,p不是野指针。
   this->len =s1.len;
}

ResourceToCopy ::
~ResouceToCopy()
{
     delete []p;
}