句柄类的出现是为了解决用户使用指针时须要控制指针的载入和释放的问题。
用指针訪问对象非常easy出现悬垂指针或者内存泄漏的问题。
为了解决这些问题,有很多方法能够使用,句柄类就是当中之中的一个。
句柄类是一种包装类。用于存储和管理基类的对象指针,减轻用户使用对象的负担。
句柄类使用指针运行操作,虚成员因为既能够指向基类型又能够指向派生类型,所以其行为将在运行时依据句柄实际绑定的对象而变化。
句柄类的设计有两个重要的考虑因素:
class Sales_item { //Sales_item 为handle类
public:
Sales_item():p(0), use(new size_t(1)) {}
Sales_item(const Item_base& item): p(item.clone()), use(new size_t(1)) {}
Sales_item(const Sales_item& item):p(item.p), use(item.use) { ++*use; }
~Sales_item() { decr_use(); }
Sales_item& operator=(const Sales_item&);
const Item_base* operator->() const;
const Item_base& operator*() const;
private:
void decr_use();
private:
Item_base *p;
size_t *use;
};
Sales_item& Sales_item::operator=(const Sales_item& rhs)
{
++*rhs.use;
decr_use();
p = rhs.p;
use = rhs.use;
return *this;
}
const Item_base* Sales_item::operator->() const
{
if(p)
return p;
else
throw logic_error("unbound Sales_item");
}
const Item_base& Sales_item::operator*() const
{
if(p)
return *p;
else
throw logic_error("unbound Sales_item");
}
void Sales_item::decr_use()
{
if( --*use == 0 )
{
delete p;
delete use;
}
}
class Item_base{
public:
virtual Item_base* clone() const { return new Item_base(*this); }
};
以上代码就可以将Item_base类的指针包装起来。通过对Handler类对象的*和->操作。就可以直接訪问到所包装的Item_base类型对象。
class Query {
friend Query operator~ (const Query&);
friend Query operator| (const Query&, const Query&);
friend Query operator& (const Query&, const Query&);
private:
Query(Query_base *query): q(query), use(new size_t(1)) { }
public:
Query(const string& s): q(new WordQuery(s)), use(new size_t(1)) { }
Query(const Query &c): q(c.q), use(c.use) { ++*use; }
Query& operator= (const Query&);
~Query(){ decr_use(); }
set<line_no> eval(const TextQuery &t) const
{
return q->eval(t);
}
private:
void decr_use();
private:
Query_base *q;
size_t *use;
};
void Query::decr_use()
{
if ( --*use == 0 )
{
delete q;
delete use;
}
}
Query& Query::operator=(const Query& rhs)
{
++*rhs.use;
decr_use();
q = rhs.q;
use = rhs.use;
return *this;
}原文:https://www.cnblogs.com/ldxsuanfa/p/10546940.html