[英]How to call virtual function of derived class through base class pointer
我們來看看這段代碼:
class CBase
{
public:
virtual vfunc() { cout << "CBase::vfunc()" << endl; }
};
class CChild: public CBase
{
public:
vfunc() { cout << "CChild::vfunc()" << endl; }
};
int main()
{
CBase *pBase = new CBase;
((CChild*)pBase)->vfunc(); // !!! important
delete pBase;
return 0;
}
輸出是:
CBase::vfunc()
但我想看看:CChild :: vfunc()
顯式((CChild *)pBase)強制轉換為“CChild *”。 那么為什么調用派生的vfunc()我需要用以下代碼替換“important”字符串:((CChild *)pBase) - > CChild :: vfunc();
這不是它的工作原理 - 這是:
CBase *pBase = new CChild;
pBase->vfunc();
virtual
函數調用在指針和引用上動態解析(除非您像顯示的那樣顯式調用該方法)。 這意味着你告訴編譯器指針是什么並不重要,它將在vftable中查找方法。 其中,在你的情況,是vftable
的CBase
。
你不能。 *pBase
是CBase
類型的對象。 您不能將它視為CChild
因為它不是CChild
對象。
使用CChild*
為CChild*
獲得的指針會導致程序顯示未定義的行為。
其他答案提出了重點 - 補充:如果您實際上可能正在處理CChild
(例如,它是作為參數傳遞的引用),那么您可以使用dynamic_cast
進行向下轉換。 然而,高度依賴dynamic_cast
通常表明您的設計出了問題。
演員的詳細信息可以在這里找到: http : //msdn.microsoft.com/en-us/library/cby9kycs(v = vs。80).aspx
因此,該過程需要通過dynamic_cast
將CBase
參數轉換為CChild
,如果引用是CChild
並且dynamic_cast
成功,那么您可以確定您正在處理CChild
,然后您可以安全地將其用作CChild
。
這里的問題似乎很簡單。 CBase無法神奇升級到CChild! 讓我重寫你的例子並添加一些評論。 它應該是自我解釋的......
#include <iostream>
class CBase {
public:
virtual void vfunc() { std::cout << "CBase::vfunc()" << std::endl; }
virtual ~CBase(){} // Virtual destructor... extremely important! I'll let you figure out why as an excercise
};
class CChild: public CBase {
public:
void vfunc() { std::cout << "CChild::vfunc()" << std::endl; }
~CChild(){} // Is this destructor called? When? Try adding some std::cout to each destructor
};
int main()
{
CBase *ptr1 = new CBase;
CBase *ptr2 = new CChild;
ptr1->vfunc(); // ptr1 points to an instance of CBase. This is what's important!!
ptr2->vfunc(); // ptr2 points to an instance of CChild, which can be referenced to as a CBase
delete ptr1;
delete ptr2;
}
輸出:
CBase::vfunc()
CChild::vfunc()
PS:我剛剛意識到我在派對上已經晚了5年,但是因為我發現了這方面的教育價值,所以我會發布它!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.