拿智能指针举例,shared_ptr,即我们平时使用比较多的智能指针是非侵入式的,boost库中提供了这个指针。
那么什么是侵入式指针呢。下面给出大概的代码。
template <class T> class IntrusivePtr { public: IntrusivePtr(T* ptr) { m_pObj = ptr; if (m_pObj != 0) { m_pObj->Addref(); } } ~IntrusivePtr() { if (m_pObj != 0) { m_pObj->Release(); m_pObj = 0; } } T* operator->() const { return m_pObj; } private: T* m_pObj; };
侵入式指针使用方法比较特殊。假如一个普通类MyClass需要被智能指针类来管理,则需要修改MyClass类的代码,实现引用计数变量及其引用计数相关管理方法。指针类使用时初始化并保存指向MyClass的指针,添加删除引用计数则直接调用MyClass中的方法。
为了方便使用,实现以下类:
template <class T> class IntrusivePtrPlugIn { public: IntrusivePtrPlugIn() : m_nRefCnt(0) {} virtual ~IntrusivePtrPlugIn() {} inline sint32 GetCount() { return m_nRefCnt; }; inline sint32 Addref() { return ++m_nRefCnt; } inline sint32 Release() { m_nRefCnt--; if (m_nRefCnt == 0) { delete this; } return m_nRefCnt; } private: sint32 m_nRefCnt; // 禁用 IntrusivePtrPlugIn (const IntrusivePtrPlugIn&); const IntrusivePtrPlugIn &operator = (const IntrusivePtrPlugIn&); };
有了侵入指针侵入对象类IntrusivePtrPlugIn,MyClass只需要从IntrusivePtrPlugIn<MyClass>类来继承,即可嵌入引用计数相关的方法,不用添加引用计数维护相关的代码。
侵入式指针的引用计数由原本被使用的类来维护,好处是被使用的原有对象具备了新加入的功能,即引用计数的相关方法,可以寻找到引用计数相关的信息。
不光智能指针,其他类也是一样,当一个原本对象想通过自己的this指针就可以获得新加入功能的相关信息时,就可以使用侵入式的思想,将新功能相关的寻找或实现方法加入到类之中。
比如普通的数组,如vector<MyClass>声明的对象,其中的元素MyClass的对象并不具备查看数组相关信息的能力,如果想在对象中能够寻找到使用它的类的相关信息,可以参照上面例子:
1.声明一个数组对象类ArrayItem类,对象类为模板类,模板类型对应数组中元素的类型,类中保存数组项索引或数组类的指针。
2.定义MyClass类时,在原有继承基础上再从ArrayItem<MyClass>继承,使其具备寻找数组的方法。
3.在此基础上,重新定义Array类,使用此类管理带有ArrayItem方法的数组对象。
这样,一个可以上下互相寻找的数组就完成了。
总结:当为一个类A扩展一些与其相关的功能B时,如果A希望了解新功能B的信息或寻找方法,则可以声明一个嵌入对象C,使类A从C继承,再由B对A进行管理。