一、智能指針
在C++語(yǔ)言編程時(shí),當(dāng)類(lèi)中有指針成員時(shí),一般有兩種方式來(lái)管理指針成員:一是采用值型的方式管理,每個(gè)類(lèi)對(duì)象都保留一份指針指向的對(duì)象的拷貝;另一種更優(yōu)雅的方式是使用智能指針,從而實(shí)現(xiàn)指針指向的對(duì)象的共享。
智能指針(smartpointer)的一種通用實(shí)現(xiàn)技術(shù)是使用引用計(jì)數(shù)(referencecount)。智能指針類(lèi)將一個(gè)計(jì)數(shù)器與類(lèi)指向的對(duì)象相關(guān)聯(lián),引用計(jì)數(shù)跟蹤該類(lèi)有多少個(gè)對(duì)象共享同一指針。
每次創(chuàng)建類(lèi)的新對(duì)象時(shí),初始化指針并將引用計(jì)數(shù)置為1;當(dāng)對(duì)象作為另一對(duì)象的副本而創(chuàng)建時(shí),拷貝構(gòu)造函數(shù)拷貝指針并增加與之相應(yīng)的引用計(jì)數(shù);對(duì)一個(gè)對(duì)象進(jìn)行賦值時(shí),賦值操作符減少左操作數(shù)所指對(duì)象的引用計(jì)數(shù)(如果引用計(jì)數(shù)為減至0,則刪除對(duì)象),并增加右操作數(shù)所指對(duì)象的引用計(jì)數(shù);調(diào)用析構(gòu)函數(shù)時(shí),析構(gòu)函數(shù)減少引用計(jì)數(shù)(如果引用計(jì)數(shù)減至0,則刪除基礎(chǔ)對(duì)象)。
智能指針詳解:
包括:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array、boost::weak_ptr、boost::intrusive_ptr
二、智能指針的一般實(shí)現(xiàn) www.jamo123.com
智能指針通常使用類(lèi)模板來(lái)實(shí)現(xiàn)。模擬類(lèi)指針的各種行為。但是,其最重要的作用是對(duì)類(lèi)指針成員的管理,防止懸垂指針的出現(xiàn)。
template<classT>
classSmartPointer{
public:
SmartPointer(T*t):pt(t){}
T&operator*(){return*pt;}
T*operator->(){returnpt;}
private:
T*pt;
};
三、引用計(jì)數(shù)的實(shí)現(xiàn)
為了實(shí)現(xiàn)引用計(jì)數(shù),我們定義一個(gè)_counter類(lèi)來(lái)記錄引用次數(shù),把_counter類(lèi)的所有成員設(shè)定為private,因?yàn)槠渌念?lèi)型并不需要訪問(wèn)_counter,只有SmartPointer對(duì)其進(jìn)行操作就行了,SmartPointer將設(shè)為其友元類(lèi)。
class_counter{
template<classT>friendclassSmartPointer;
_counter(intu):use(u){}
~_counter(){}
intuse;
};
在SmartPointer類(lèi)中,保留_counter的指針。
template<classT>
classSmartPointer{
public:
SmartPointer(T*t):pc(new_counter(1)){
cout《"SmartPointer::SmartPointer()invodeduseis:"《pc->use《endl;
this->pt=t;
}
SmartPointer(SmartPointer<T>&rhs){
this->pc=rhs.pc;
this->pt=rhs.pt;
this->pc->use++;
cout《"SmartPointercopyinvokeduseis:"《pc->use《endl;
}
~SmartPointer(){
pc->use--;
cout《"SmartPointer::~SmartPointer()invodeduseis:"《pc->use《endl;
if(pc->use==0)
{
deletept;
deletepc;
}
}
SmartPointer<T>&operator=(SmartPointer<T>rhs){
if(rhs==*this){
return*this;
}
this->pt=rhs.pt;
this->pc=rhs.pc;
this->pc->use++;
cout《"SmartPointer::operator=()invokeduseis:"《pc->use《endl;
return*this;
}
private:
T*pt;
_counter*pc;
};
例如:我們有一個(gè)HasPtr類(lèi),其類(lèi)成員中有一個(gè)為指針*p.
classHasPtr{
public:
HasPtr(intval):value(val),p(newint(3)){
cout《"HasPtr::HasPtr()invoked"《endl;
}
~HasPtr(){deletep;cout《"HasPtr::~HasPtr()invoded"《endl;}
private:
int*p;
intvalue;
};
如果如下調(diào)用:
HasPtr*php=newHasPtr(3);
SmartPointer<HasPtr>psp(php);
SmartPointer<HasPtr>npsp(psp);
我們現(xiàn)在有兩個(gè)智能指針對(duì)象,指向同一個(gè)HasPtr對(duì)象,
實(shí)現(xiàn) www.lefeng123.com
_counter的use成員(引用計(jì)數(shù))為2.
四、測(cè)試
intmain(void)
{
HasPtr*php=newHasPtr(3);
SmartPointer<HasPtr>psp(php);
SmartPointer<HasPtr>npsp(psp);
SmartPointer<HasPtr>nnpsp=npsp;
return0;
}