將指針指向派生類指向指針指向基類的方法是合法的,即使基類沒有聲明任何方法,特別是的「鑄造」的方法是通過型基類的對象被調用,如follows:將指向派生類的方法的指針投射到指向基類的方法的指針
// works in VS 2008 and g++ 4.5.3
struct Base
{
};
struct Fuu : public Base
{
void bar(){ std::cout << "Fuu::bar" << std::endl; }
void bax(){ std::cout << "Fuu::bax" << std::endl; }
};
struct Foo : public Base
{
void bar(){ std::cout << "Foo::bar" << std::endl; }
void bax(){ std::cout << "Foo::bax" << std::endl; }
};
typedef void (Base::*PtrToMethod)();
int main()
{
PtrToMethod ptr1 = (PtrToMethod) &Foo::bax;
PtrToMethod ptr2 = (PtrToMethod) &Fuu::bax;
Base *f1 = new Foo;
Base *f2 = new Fuu;
(f1->*ptr1)();
(f2->*ptr2)();
}
對於「普通」指針,該規則被稱爲「協方差」:您可以將「派生*」轉換爲「基本*」(因爲「派生」是「基本」),而不是相反方向(因爲「 Base *'不一定指向'Derived')。對於_pointers-to-member_,這個規則被稱爲「contravariance」,並且基本上是與之相反的:您可以將'T Base :: *'轉換爲'T Derived :: *'(因爲'Base'的成員也是存在於一個Derived'對象中)而不是其他方式(因爲'Derived'可以將成員添加到'Base'中)。另外_please_不使用C風格演員:他們不安全,不清楚,難以發現。 –
精細打印:您的示例雖然編譯和「有效」,但可能不合法。或者將'Base *''f1'強制轉換爲'Foo *'(如果你確定的話''static_cast'',如果你不需要''dynamic_cast''但是它需要'Base'至少有一個'virtual'函數] ),或者添加虛擬功能到'Base'的公共接口。 –