拷贝控制与资源管理

来源:互联网 发布:苹果有些软件不信任 编辑:程序博客网 时间:2024/06/06 02:12

定义:管理类外资源的类必须定义拷贝控制成员
拷贝操作:类值拷贝或类指针拷贝
对于内置类型的成员(非指针)一般让他们类值拷贝,对于指针成员如何拷贝决定了这样的类是类值拷贝还是类指针拷贝
1,类值拷贝:改动拷贝副本源对象不会发生改变
2,类指针拷贝:副本与对象会同时发生改变
但是IO类与unique_ptr不支持拷贝和赋值
类值拷贝

class hasptr{public:hasptr(const string&s=string()):p(newstring(s)),i(10){}hasptr(const hasptr&h):p(new string(*h.p),i(h.i){}hasptr& operator=(const hasptr&);~hasptr(){delete p;} //定义析构函数,释放指针指向的内存private:string *p;int i;};

拷贝构造函数创建自己的string副本,然后让指针指向这个string副本(第五行代码)

p(new string(*h.p)

类指针拷贝
定义:拷贝指针成员而不是它指向的string
即使拷贝前后两个指针都指向相同的内存,我们仍然要定义自己的析构函数来释放构造函数分配的string内存
建议:让类展现类似指针行为的好方法是使用shared_ptr来管理类中的资源,含有shared_ptr的类要自己记录有多少个用户共享它指向的对象
注意:引用计数不能直接作为类的成员
将计数器保存在动态内存中,当创建一个对象时,我们分配一个新的计数器。当拷贝或赋值时,我们拷贝指向计数器的指针。因此副本和原对象都指向相同的计数器
1,类的构造函数初始化数据成员外,创建一个引用计数器并初始化为1
2,拷贝构造拷贝数据成员(包含引用计数器)并递增引用计数
3,析构函数递减引用计数,如引用计数=0,释放内存
4,拷贝赋值运算符递增右侧对象的引用计数,递减左侧的引用计数(拷贝时先销毁左侧的对象再把右侧的对象拷贝给左侧)

class hasptr{ hasptr(const string&s=string()): p(new string(s)),i(0),use(new size_t(1)){} hasptr(const hasptr&h):p(h.p),i(h.i),use(h.use){++*use;}//拷贝副本与源对象都指向相同的引用计数器 hasptr& oprator=(const hasptr&); ~hasptr(); private: string *p; size_t *use; int i; hasptr::~hasptr() {   if(--*use==0){delete p;delete use;} }

析构函数递减引用计数,如果引用计数=0那么释放构造函数分配的内存(数据成员内存,引用计数器的内存)

0 0
原创粉丝点击