19、C++ Primer 4th 笔记,类管理指针成员
1、一般采取三种方法
1)指针成员采取常规指针型行为。这样的类具有指针的所有缺陷但无需特殊的复制控制。
2)类可以实现所谓的“智能指针”行为。指针所指向的对象是共享的,但类能够防止悬垂指针。
3)类采取值型行为。指针所指向的对象是唯一的,由每个类对象独立管理。
2、类中定义指针时,需要考虑的有:类的复制,类的赋值,类的析构,共享对象,及悬垂指针。
3、定义智能指针
一个行为类似指针但也提供其他功能的类。智能指针的一个通用形式是接受指向动态分配对象的指针并负责删除该对象。用户分配对象,但由智能指针类删除它。智能指针类需要实现复制控制成员来管理指向共享对象的指针。引用计数是实现智能指针的常用方法。
注意:是由构造函数设置共享对象的状态并将使用计数置为1。
1)引入使用计数
定义智能指针的通用技术是采用一个使用计数(use count,也称为引用计数,reference count)。智能指针类将一个计数器与类中成员指向的对象相关联。使用计数为0时,删除对象。
对一个对象进行赋值时,赋值操作符减少左操作数对象的使用计数的值(如果使用计数减至0,则删除对象),并增加右操作数对象的使用计数的值。
2)实现使用计数有两种策略。这里引入一种:定义一个单独的具体类用以封装使用计数和相关指针。
示例
class U_Ptr { friend class HasPtr; int *ip; size_t use; U_Ptr(int *p):ip(p), use(1){} ~U_Ptr() {delete ip;} }; class HasPtr { public: HasPtr(int *p, int i):ptr(new U_Ptr(p)), val(i) {} HasPtr(const HasPtr& orig):ptr(orig.ptr), val(orig.val) { ++ptr->use; } HasPtr& operator=(const HasPtr&); ~HasPtr() { if (--ptr->use == 0) delete ptr; } private: U_Ptr *ptr; int val; }; HasPtr& HasPtr::operator=(const HasPtr& rhs) { ++rhs.ptr->use; if (--ptr->use == 0) delete ptr; ptr = rhs.ptr; val = rhs.val; return *this; }
4、定义值型类
与处理智能指针不同的是,给指针成员提供值语义。具有值语义的类所定义的对象,其行为很像算术类型的对象:复制值型对象时,会得到一个不同的新副本。当发生复制时,改变的是指针所指向的值,而不是指针。
示例
class HasPtr { public: HasPtr(const int &p, int i):ptr(new int(p)), val(i){} HasPtr(const HasPtr &orig):ptr(new int(*orig.ptr)), val(orig.val){} HasPtr& operator=(const HasPtr&); ~HasPtr() {delete ptr;} private: int *ptr; int val; }; HasPtr& HasPtr::operator=(const HasPtr& rhs) { *ptr = *rhs.ptr; //是赋值 val = rhs.val; return *this; }
参考
[1] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100250413207/
[2] http://blog.163.com/zhoumhan_0351/blog/static/39954227201032845132592/
[3] http://blog.163.com/zhoumhan_0351/blog/static/399542272010318112048522/
[4] http://blog.163.com/zhoumhan_0351/blog/static/39954227201032092854732/
[5] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826/
[6] http://blog.163.com/zhoumhan_0351/blog/static/39954227201012465955824/