自定析构意味着也要自定拷贝和赋值,自定拷贝意味着要自定赋值

一、需要析构意味着拷贝和赋值

如果自定义析构意味着有指针及其指向的动态内存,采用系统合成的拷贝和赋值将会默认共享动态内存,一旦一个对象离开其作用域,将会致使delete运算符多次释放同一块内存。

类使用指针管理内存,如下:

class HasPtr
{
public:
	HasPtr(const string &s=string()):ps(new string(s),i(0)){}//参数中分配动态内存
private:
    ~HasPtr(){delete ps;}//涉及到动态内存必须自定义析构delete这部分内存
	string * ps;
	int i;
};

ps实现了对new string的管理。如果用户不自定义拷贝和赋值,编译器将会默认拷贝指针本身,拷贝不会对动态内存进行拷贝。下面这个例子能够告知为什么需要定义拷贝和赋值:

{
	HasPtr a;//构造
	HasPtr b=a;//拷贝构造,ok!b对象也有一个指针指向a对象动态内存
	HasPtr c;
	c=b;//拷贝赋值,ok! c对象也有一个指向a对象动态内存
}

当对象a离开其定义域,调用析构函数进行delete动态内存,成功删除了!接着轮到对象b析构,再次调用析构函数delete已经析构的a中动态内存,这就有问题了,这部分内容已经不存在了,因此是一个严重的设计错误;同理c也将会析构一次,同样是出错。

二 、需要拷贝也需要赋值

拷贝定义了拷贝应该完成的操作,如序列号+1实现每一个对象都有一个独一序列号,如果没有封住赋值是不是实现不了了?没错,所以拷贝也要赋值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章