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

时间:2023-03-09 04:10:37
C++ 句柄类的原理以及设计

句柄类存在的意义是为了弥补将派生类对象赋给基类对象时发生的切片效应。比如以下的程序:

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 once
class 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;
else
throw std::logic_error("unbounded Handles");
} const Base* Handles::operator->()const
{
if(p)
return p;
else
throw 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");
}