在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、容器与继承在容器中保存有继承关系的对象,如果定义成保存基类对象,则派生类将被切割,如果定义成保存派生类对象,则保存基类对象又成问题(基类对象将被强制转换成派生类对象,而派生类中定义的成员未被初始化)。 唯一的可行的选择是容器中保存对象的指针。但是需要用户管理对象和指针。C++中一个通用的技术是包装类(cover)或句柄类(handle)。用句柄类存储和管理类指针。
句柄类大体上完成两方面的工作: a,管理指针,这与智能指针的功能类似。b,实现多态,利用动态绑定,是得指针既可以指向基类,也可以指向派生类。 包装了继承层次的句柄有两个重要的设计考虑因素: 1)像对任何保存指针的类一样,必须确定对复制控件做些什么。包装了继承层次的句柄通常表现得像一个智能指针或者像一个值。 2)名柄类决定句柄接口屏蔽还是不屏蔽继承层次,如果不屏蔽继承层次,用户必须了解和使用基本层次中的对象(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> #include <stdexcept> using namespace std; //基类 class Base { public: Base(int a_=1, string na="Base"):m_base(a_),name(na) {} Base(const Base &rhs)//复制构造 { m_base = rhs.m_base; name = rhs.name; } //clone函数来返回一个自身的副本 virtual Base* clone() const { return new Base(*this); } const string getName() const//返回对象名字 { return name; } virtual int compute()const// 返回整数成员的平方 { return m_base*m_base; } private: int m_base; string name; }; // 派生类 class Derived:public Base { public: Derived(int a=2,string na="Derived", int b=2):Base(a,na),m_der(b) {} Derived(const Derived &rhs):Base(rhs) //copy constructor { m_der = rhs.m_der; } Derived* clone() const { return new Derived(*this); } int compute()const//返回成员平方和加上派生类新成员 { return Base::compute() + m_der; } private: int m_der; }; //句柄类 class Handle { public: //默认构造函数 1 //指针置0,不与任何对象关联,计数器初始化为1 Handle():pBase(0),use(new int(1)) {} //析构函数 ~Handle() { des_use(); } //接受Base对象 item的构造函数,注意引用。 2 Handle(const Base &item):pBase(item.clone()),use(new int(1)) {} //复制控制函数:管理计数器和指针。 3 Handle(const Handle &ha):pBase(ha.pBase),use(ha.use) { ++*use; } //赋值操作符 Handle& operator=(const Handle& rhs) { ++*rhs.use;//右操作数的引用计数+1 des_use();//处理左操作数 //复制右操作数 pBase = rhs.pBase; use = rhs.use; //返回左操作数的引用 return *this; } //重载箭头操作符 const Base* operator->() const { if(pBase) return pBase; else throw logic_error("unbound Handle"); } //重载解引用操作符 const Base &operator*() const { if(pBase) return *pBase; else throw logic_error("unbound Handle"); } // 输出引用计数 void print_use() { cout<<pBase->getName()<<" use count "<<*use<<endl; } private: //指向引用计数 int *use; //指向基类的指针,也可以用来指向派生类 Base *pBase; void des_use() { if(--*use == 0) { cout<<pBase->getName()<<" delete\n"; delete pBase; delete use; } } }; int main() { Handle h1(Base(2,"Base")); h1.print_use(); cout<<"Base compute:"<<(*h1).compute()<<endl; Handle h2(h1); h2.print_use(); cout<<"Base compute:"<<h2->compute()<<endl; cout<<"*------------------------------------------*\n"; Handle h3(Derived(3, "derive", 3)); h1 = h3; h1.print_use(); cout<<"Derive compute:"<<(*h1).compute()<<endl; return 0; } 二、句柄类
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论