C++ 句柄类的原理以及设计

来源:互联网 发布:基金中央数据交换平台 编辑:程序博客网 时间:2024/05/09 08:00
句柄类存在的意义是为了弥补将派生类对象赋给基类对象时发生的切片效应。例如下面的程序:
multimap<Base> basket;Base base;Derived derive;basket.insert(base);//ok,add copy of base;basket.insert(derive);//ok,but derive sliced down to its base part.

也就是说在把派生类的对象赋值给基类的时候,会发生切片效益,派生类的非基类部分会被切掉,那么就失去了本身的意义。为了解决这个问题我们可以
使用基于基类的指针或者引用,但是设计到指针问题的话就涉及到资源不使用后的释放问题。这就引出了句柄类,它类似智能指针,可以在我们复制资源
的时候不用去担心内存泄露的问题。整个程序的设计如下所示:
//Base.h#pragma onceclass Base{public:Base(void);virtual ~Base(void);virtual Base* clone() const;virtual void fine() const;private:int mb;};

//Base.cpp#include "Base.h"#include <iostream>using namespace std;Base::Base(void):mb(12){}Base::~Base(void){}Base* Base::clone() const{return new Base(*this);}void Base::fine() const{cout<<"Base fine function"<<endl;}

//Derive.h#pragma once#include "base.h"class Derive :public Base{public:Derive(void);virtual ~Derive(void);virtual Derive* clone() const;virtual void fine() const;private:int md;};

//Derive.cpp#include "Derive.h"#include <iostream>using namespace std;Derive::Derive(void):Base(),md(13){}Derive::~Derive(void){}Derive* Derive::clone() const{return new Derive(*this);}void Derive::fine() const{cout<<"Derive fine function"<<endl;}

//Handles.h #pragma once#include "Base.h"#include <iostream>class Handles{public:Handles(void);Handles(const Base&);Handles(const Handles& h);~Handles(void);const Base* operator->()const;const Base& operator*()const;Handles& operator=(const Handles&);private:Base*p;std::size_t*use;void dec_use(){if(--*use == 0){delete p;delete use;std::cout<<"delete resource"<<std::endl;}}};

//Handle.cpp #include "Handles.h"Handles::Handles(void):p(NULL),use(new size_t(1)){}Handles::Handles(const Handles& h):p(h.p),use(h.use){++*use;}Handles::Handles(const Base& item):p(item.clone()),use(new std::size_t(1)){}const Base& Handles::operator*()const{if(p) return *p;elsethrow std::logic_error("unbounded Handles");}const Base* Handles::operator->()const{if(p) return p;elsethrow std::logic_error("unbounded Handles");}Handles& Handles::operator=(const Handles& h){++*h.use;dec_use();p = h.p;use = h.use;return *this;}Handles::~Handles(){dec_use();}

//main.cpp#include <iostream>#include "Handles.h"#include "Derive.h"#include <vector>using namespace std;void main(){vector<Handles> mb;Base b;Derive d;mb.push_back(Handles(b));mb.push_back(Handles(d));mb[0]->fine();mb[1]->fine();system("pause");} 



0 0
原创粉丝点击