C++句柄类

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C++句柄类
⼀、容器与继承
在容器中保存有继承关系的对象时,如果定义成保存基类对象,则派⽣类将被切割,如果定义成保存派⽣类对象,则保存基类对象⼜成问题(基类对象将被强制转换成派⽣类对象,⽽派⽣类中定义的成员未被初始化)。

唯⼀的可⾏的选择是容器中保存对象的指针。

但是需要⽤户管理对象和指针。

C++中⼀个通⽤的技术是包装类(cover)或句柄类(handle)。

⽤句柄类存储和管理类指针。

句柄类⼤体上完成两⽅⾯的⼯作:
1. 管理指针,这与智能指针的功能类似。

2. 实现多态,利⽤动态绑定,是得指针既可以指向基类,也可以指向派⽣类。

包装了继承层次的句柄有两个重要的设计考虑因素:
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>
using namespace std;
// base class
class 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, ) {
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.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(e) {
++*use;
}
//重载赋值操作符
Handler &operator=(const Handler &right) {
++*(e);
decrese_use();
pBase = right.pBase;
use = e;
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;
return0;
}
⼆、句柄类
句柄类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;
return0;
}
输出:
Base constructor called!
Base constructor called!
Base copy called
Base deleted
Base use: 1
Base compute:4
Base use: 2
Base use: 2
Base compute:4
-------------------------------------
Base constructor called!
Derived constructor called
Base constructor called!
Derived constructor called
Derived copy called
Derived deleted
Base deleted
derived use: 2
derived use: 2
Derived compute:12
system automatic delete begin
Base is going to be deleted!
Base deleted
derived is going to be deleted!
Derived deleted
Base deleted
主函数中使⽤Base对象创建了Handler对象h1,并由h1构造Handler对象h2,通过输出可以发现Handler对象的引⽤计数由1变为2。

然后使⽤Derived对象创建Handler对象h3,并将其赋值给h1,对h1,h3 输出其引⽤计数,可知引⽤计数均为2.。

相关文档
最新文档