C++ 句柄类
来源:互联网 发布:网络包工头在哪找活 编辑:程序博客网 时间:2024/05/16 05:34
一、容器与继承
在容器中保存有继承关系的对象时,如果定义成保存基类对象,则派生类将被切割,如果定义成保存派生类对象,则保存基类对象又成问题(基类对象将被强制转换成派生类对象,而派生类中定义的成员未被初始化)。
唯一的可行的选择是容器中保存对象的指针。但是需要用户管理对象和指针。C++中一个通用的技术是包装类(cover)或句柄类(handle)。用句柄类存储和管理类指针。
句柄类大体上完成两方面的工作:
管理指针,这与智能指针的功能类似。
实现多态,利用动态绑定,是得指针既可以指向基类,也可以指向派生类。
包装了继承层次的句柄有两个重要的设计考虑因素:
像对任何保存指针的类一样,必须确定对复制控件做些什么。包装了继承层次的句柄通常表现得像一个智能指针或者像一个值。
名柄类决定句柄接口屏蔽还是不屏蔽继承层次,如果不屏蔽继承层次,用户必须了解和使用基本层次中的对象(objects in theunderlying hierarchy)。
下面通过一个我自己写的一个简单的例子来说明这个问题:
这个例子程序包括一个基类,一个派生类,还有一个句柄类。
其中,基类有2个私有成员,数值m_base和程序名字name。派生类有一个新的私有成员,m_der。
派生类和基类有虚函数compute。基类的compute它计算基类成员m_base平方。派生类的compute计算m_base平方和m_der之和。
句柄类有两个数据成员,分别是指向引用计数的指针( 这里必须是指针,复制时引用计数复制指针的值,保证一个实例化对象只有一个引用计数)和指向基类或者是其派生类的指针。
#include<iostream>#include<string>#include<exception>using namespace std;// base classclass Base {public: //basic constructor Base(int m_base = 1, string name = "Base") : m_base(m_base), name(name) { cout << "Base constructor called!" << endl; } //copy constructor Base(const Base &base) : Base(base.m_base, base.name) { cout << "Base copy called" << endl; } virtual Base *clone() const { return new Base(*this); } const string getName() { return name; } virtual int compute() const { return m_base * m_base; } virtual ~Base(){ cout<<"Base deleted"<<endl; }protected: int m_base; string name;};class Derived : public Base {public: //basic constructor Derived(int m_base, string name, int m_der) : Base(m_base, name), m_der(m_der) { cout << "Derived constructor called" << endl; } //copy constructor Derived(const Derived &derived) : Derived(derived.m_base, derived.name, derived.m_der) { cout << "Derived copy called" << endl; } virtual Derived *clone() const { return new Derived(*this); } virtual int compute() const { //调用父类中定义的方法 return Base::compute() + m_der; } virtual ~Derived(){ cout<<"Derived deleted"<<endl; }private: int m_der;};class Handler {public: //默认构造函数 Handler() : pBase(NULL), use(new int(1)) { } //一般构造函数 Handler(const Base &item) : pBase(item.clone()), use(new int(1)) { } //复制构造函数 //每复制一次,引用计数就加1 Handler(const Handler &ref) : pBase(ref.pBase), use(ref.use) { ++*use; } //重载赋值操作符 Handler &operator=(const Handler &right) { ++*(right.use); decrese_use(); pBase = right.pBase; use = right.use; return *this; } //重载箭头操作符 const Base *operator->() const { if (pBase) return pBase; else throw logic_error("unbound Handler!"); } //重载解引用操作符 const Base &operator* () const{ if(pBase) return *pBase; else throw logic_error("unbound Handler"); } void print_use() { cout << pBase->getName() << " use: " << *use << endl; } //析构函数 ~Handler() { decrese_use(); }private: //此处必须使用指针,保证一个Base实例只对应一个引用计数 int *use; Base *pBase; void decrese_use() { if (--*use == 0) { cout << pBase->getName() << " is going to be deleted!" << endl; delete pBase; } }};int main() { Handler h1(Base(2,"Base")); h1.print_use(); cout<<"Base compute:"<<(*h1).compute()<<endl; Handler h2(h1); h2.print_use(); cout<<"Base compute:"<<(*h2).compute()<<endl; cout<<"-------------------------------------"<<endl; Handler h3(Derived(3,"derived",3)); h1=h3; h1.print_use(); cout<<"Derived compute:"<<(*h1).compute()<<endl; cout<<"system automatic delete begin"<<endl; return 0;}
二、句柄类
句柄类Handle 有3个构造函数:默认构造函数,复制构造函数,和接收基类Base对象的构造函数。为了保证 在接收基类Base对象的构造函数中 复制具体对象的时候实现动态调用,得到正确类别的实例,我们在类中定义了虚函数clone。
Base
virtual Base *clone() const { return new Base(*this);}
Derived
virtual Derived *clone() const { return new Derived(*this);}
三、运行结果
主函数调用:
int main() { Handler h1(Base(2,"Base")); h1.print_use(); cout<<"Base compute:"<<(*h1).compute()<<endl; Handler h2(h1); h2.print_use(); cout<<"Base compute:"<<(*h2).compute()<<endl; cout<<"-------------------------------------"<<endl; Handler h3(Derived(3,"derived",3)); h1=h3; h1.print_use(); cout<<"Derived compute:"<<(*h1).compute()<<endl; cout<<"system automatic delete begin"<<endl; return 0;}
输出:
Base constructor called!Base constructor called!Base copy calledBase deletedBase use: 1Base compute:4Base use: 2Base use: 2Base compute:4-------------------------------------Base constructor called!Derived constructor calledBase constructor called!Derived constructor calledDerived copy calledDerived deletedBase deletedderived use: 2derived use: 2Derived compute:12system automatic delete beginBase is going to be deleted!Base deletedderived is going to be deleted!Derived deletedBase deleted
主函数中使用Base对象创建了Handler对象h1,并由h1构造Handler对象h2,通过输出可以发现Handler对象的引用计数由1变为2。然后使用Derived对象创建Handler对象h3,并将其赋值给h1,对h1,h3 输出其引用计数,可知引用计数均为2.
转载自:C++ 句柄类
- 【C++】浅谈C++句柄类
- c句柄
- c句柄
- [C/C++] Very very good !!! 句柄类
- C++_Primer 15.8 句柄类与继承
- c++句柄
- C++/MFC 句柄
- C 语言句柄handle
- C 句柄 回调
- [C++]什么是句柄?为什么会有句柄?
- 句柄类
- 句柄类
- 句柄类
- 句柄类
- 句柄类
- 句柄类
- 句柄类
- 句柄类
- C++ 设计模式
- cocos2dx cc.SpriteBatchNode运用
- rand()和srand()产生为随机数方法
- CentOS7开机时的菜单选择时间由5秒缩短为2秒
- Shop项目--2.动态获取最新商品和热门商品
- C++ 句柄类
- stdint.h: No such file or directory的解决办法
- 一些提升技能的好书
- cdn 导致跨域问题
- 小朱opengl学习笔记(二)-----小白入门案例介绍
- 最简单UDP协议接收端和发送端
- C++中友元(友元函数和友元类)的用法和功能
- 5.3.1 继承的方法
- 042day(OJ枚举例题(特殊密码锁)的练习)