C++的clone函数什么时候需要重载
C++ Primer中的原話:只有析構函數應定義為虛函數,構造函數不能定義為虛函數。構造函數是在對象完全構造之前運行的,在構造函數運行的時候,對象的動態類型還不完整。在構造函數內部肯定不會出現多態現象。
如轉自:http://zhedahht.blog.163.com/blog/static/25411174201102642136998/:
class?A
{
public:
????????A()
????????{
????????????????Print();
????????}
????????virtual?void?Print()
????????{
????????????????printf("A is constructed.\n");
????????}
};
?
class?B:?public?A
{
public:
????????B()
????????{
????????????????Print();
????????}
?
????????virtual?void?Print()
????????{
????????????????printf("B is constructed.\n");
????????}
};
?
int?_tmain(int?argc, _TCHAR* argv[])
{
????????A* pA =?new?B();
????????delete?pA;
?
????????return?0;
}
答案:先后打印出兩行:A is constructed. B is constructed.?調用B的構造函數時,先會調用B的基類及A的構造函數。然后在A的構造函數里調用Print。由于此時實例的類型B的部分還沒有構造好,本質上它只是A的一個實例,他的虛函數表指針指向的是類型A的虛函數表。因此此時調用的Print是A::Print,而不是B::Print。接著調用類型B的構造函數,并調用Print。此時已經開始構造B,因此此時調用的Print是B::Print。
同樣是調用虛擬函數Print,我們發現在類型A的構造函數中,調用的是A::Print,在B的構造函數中,調用的是B::Print。因此虛函數在構造函數中,已經失去了虛函數的動態綁定特性。
但是會出現這個需求,需要一個對象a產生另一個對象b。如果a所屬的類是A,b所屬的類是B,并且B繼承A。如何用a生成b呢?
這就是一種模式,成為 原型模型:從一個對象再創建另外一個可以定制的對象,而且不需要知道任何創建的細節。
在more effective c++的 25條,有很詳細的闡述。
class NLComponent
{
public:
? ? ? ?virtual NLComponent *clone()const = 0;
}
class TextBlock:public NLComponent
{
public:
virtualTextBlock *clone() const
{
return new TextBlock(*this);
}
}
class Graphic:public NLComponent
{
public:
virtual Graphic *clone()const
?{
return new Graphic(*this);
}
}
要注意到clone這個虛函數的返回值不一致,而虛函數的定義要求,必須返回值,函數名和參數列表一致。
這是因為返回值雖不一樣,但是其基類都是一致的,所以也能實現多態。
虛函數與重載函數的比較
1-重載函數要求函數有相同的返回值類型和函數名稱,并有不同的參數序列;面虛函數要求這三項(函數名、返回值類型和參數序列)完全相同。
2-重載函數可以是成員函數或友員函數,面虛函數只能是成員函數。
3-重載函數的調用是以所傳遞參數序列的差別作為調用不同函數的依據;虛函數是根據對象的不同去調用不同類的虛函數。
4-虛函數在運行時表現出多態功能,這是C++的精髓,而重載函數則在編譯時表現出多態性。
總結
以上是生活随笔為你收集整理的C++的clone函数什么时候需要重载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最大0,1子矩阵
- 下一篇: 线程同步机制有临界区、互斥、信号量优缺点