}
};
intmain(void)
{
CSomethingsth(1,2);
CAca(&sth);
ca.Show();
CAcb(ca);//调用缺省的隐式拷贝构造函数
cb.Show();
cb.setValue(2,3);
ca.Show();
cb.Show();
ca.getSthAddress();
cb.getSthAddress();
return0;
}
上面的程序没有显式声明拷贝构造函数,运行结果如下:
可见,ca和cb中的指针成员变量sth指向的是同一个内存地址(Console输出的第5、6行),这就是为什么在cb.setValue(2,3)后,ca对应的内容也发生了改变(Console输出的第3、4行),而这不是我们所期望的;其次,我们生成了两个对象ca和cb,因此对两次调用析构函数,第一次调用析构函数的时候没有问题,因为此时sth里面有内容,第二次调用析构函数时,sth里面的内容由于在第一次调用析构函数的时候已经被delete了,所以会出现如上的错误提示。
保持其他代码不变,现在我们增加一个拷贝构造函数如下:
CA(CA&obj)
{
sth=newCSomething((obj.sth)->a,(obj.sth)->b);
}
再运行上面的程序,所得到的结果如下:
这次,ca和cb中的指针成员变量sth指向的不是同一个内存地址(Console输出的第5、6行)了,这就是为什么在cb.setValue(2,3)后,ca对应的内容保持不变,而cb的内容该如愿地改为(2,3)(Console输出的第3、4行);其次,析构函数也不会报告错误了。
3)关于拷贝构造函数另外一个完整的例子,其中包含了copyconstructor,destructor和copyassignmentoperator。
#include
usingnamespacestd;
classPoint
{
public:
int_x;
int_y;
public:
Point();
Point(int,int);
};
Point:
:
Point()
{
_x=0;
_y=0;
}
Point:
:
Point(intx,inty)
{
_x=x;
_y=y;
}
classCA
{
public:
Point*_point;
public:
CA(constPoint*);
voidsetPointValues(int,int);
voidprintCoordinates();
//需要增加的拷贝构造函数
CA(constCA&);
//需要增加的析构函数
virtual~CA();
//需要增加的拷贝赋值函数
CA&operator=(constCA&);
};
CA:
:
CA(constPoint*point)
{
_point=newPoint();//发生了动态内存分配!
因此不能缺少析构函数。
_point->_x=point->_x;
_point->_y=point->_y;
}
//需要增加的拷贝构造函数的实现
CA:
:
CA(constCA&ca)
{
_point=newPoint();
_point->_x=(ca._point)->_x;
_point->_y=(ca._point)->_y;
}
//需要增加的析构函数的实现
CA:
:
~CA()
{
if(!
_point)delete_point;
}
//需要增加的拷贝赋值函数的实现
CA&CA:
:
operator=(constCA&ca)
{
_point=newPoint();
_point->_x=(ca._point)->_x;
_point->_y=(ca._point)->_y;
return*this;
}
voidCA:
:
setPointValues(intx,inty)
{
_point->_x=x;
_point->_y=y;
}
voidCA:
:
printCoordinates()
{
cout<<"Coordinates=("<<_point->_x<<","<<_point->_y<<")"<}
intmain(void)
{
Pointapoint(1,2);
CAca(&apoint);
ca.printCoordinates();
CAcb(ca);//调用拷贝构造函数
cb.printCoordinates();
cb.setPointValues(12,12);
cb.printCoordinates();
ca.printCoordinates();
CAcc=cb;//调用拷贝赋值函数
cc.printCoordinates();
cc.setPointValues(13,13);
ca.printCoordinates();
cb.printCoordinates();
cc.printCoordinates();
return0;
}