句柄類解決C++面向對象程式設計中不能使用對象支援面向對象程式設計(必須使用指針或引用才能獲得動态綁定行為)的問題。
準備知識1:可以簡單地認為編譯器首先掃描類定義(而不是類實作),知道這個類有什麼函數、函數的原型是什麼、有什麼成員變量,成員變量的類型是什麼。然後,編譯器才會編譯其實作,是以類成員函數總能直接通路任何成員變量和函數
Example:
class A
{
public:
void fun()
{
cout<<"fun()"<<endl;
}
void print()
{
fun();
fun1();//fun1()在後面定義,但是仍然能被調用
}
void fun1()
{
cout<<"fun1()"<<endl;
}
};
int main()
{
A a;
a.print();
return 0;
}
Output:
fun()
fun1()
準備知識2:類的合成複制構造函數隻複制值(包括指針值)
class A
{
public:
A(int i):x(i),p(new int(2))
{
}
A* copy()
{
return new A(*this);//調用合成複制構造函數
}
void print()
{
cout<<"x: "<<x<<endl;
cout<<"*p: "<<*p<<endl;
}
private:
int x;
int *p;
};
int main()
{
A a(1);
A *p=a.copy();
p->print();
return 0;
}
output:
x:1
*p:2
準備知識3:智能指針,詳見C++文法基礎--智能指針
1.句柄類存儲和管理基類指針,指針所指對象的類型既可以指向基類類型對象又可以指向派生類型對象
2.包裝了繼承層次的句柄的兩個重要的設計因素
*必須确定對複制控制做些什麼
*句柄類決定句柄接口屏蔽還是不屏蔽繼承層次
3.指針型句柄
*保證複制(指派)對象時,将複制指針而不是複制對象
注:綠色代碼不分并非句柄類必須部分,隻是為了驗證句柄類工作是否正常
Example:
class base
{
public:
virtual void fun()
{
cout<<"base::fun()"<<endl;
}
virtual base* copy()
{
return new base(*this);
}
};
class derived:public base
{
public:
virtual void fun()
{
cout<<"derived::fun()"<<endl;
}
virtual derived* copy()
{
return new derived(*this);
}
};
class handle:public derived
{
public:
handle():pt(0),count(new size_t(1))
{
}
handle(base& other):pt(other.copy()),count(new size_t(1))
{
++*count;
}
handle& operator=(handle& other)
{
++*(other.count);
delete_handle();
pt=other.pt;
count=other.count;
return *this;
}
base& operator*()
{
if(pt)
{
return *pt;
}
cerr<<"derefference error!"<<endl;
}
base* operator->()
{
if(pt)
{
return pt;
}
cerr<<"error! handle has been deleted "<<endl;
}
~handle()
{
delete_handle();
}
void print()
{
cout<<"count: "<<*count<<endl;
}
private:
base *pt;
size_t *count;
void delete_handle()
{
if(--*count==0)
{
cout<<"delete_handle()"<<endl<<endl;
delete pt;
delete count;
}
}
};
int main()
{
base b;
derived d;
handle h1;
cout<<"afeter handle defult constructor(hand h1;): "<<endl;
h1.print();
cout<<endl;
handle h2(b);
cout<<"afeter handle copy constructor(hand h2(b);): "<<endl;
(*h2).fun();
h2.print();
cout<<endl;
handle h3(d);
cout<<"afeter handle copy constructor(hand h3(d);): "<<endl;
(*h3).fun();
h3.print();
cout<<endl;
h1=h3;
cout<<"afeter handle assignment constructor(h1=h3;): "<<endl;
(*h1).fun();
h1.print();
cout<<endl;
(*h3).fun();
h3.print();
return 0;
}
運作結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90zZixmWYlFbodVY1x2RjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jM2ATMxAjM4EjMycDMzEDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)