2017-07-19 27 views
1

如何確定基類(B)類的指針是否(多態)會覆蓋某個虛函數基類?運行時檢查一個實例(Base *)是否覆蓋父函數(Base :: f())

class B{ 
    public: int aField=0; 
    virtual void f(){}; 
}; 
class C : public B{ 
    public: virtual void f(){aField=5;}; 
}; 
class D: public B{}; 

int main() { 
    B b; 
    C c; 
    D d; 
    std::vector<B*> bs; 
    bs.push_back(&b); 
    bs.push_back(&c); 
    bs.push_back(&d); 
    for(int n=0;n<3;n++){ 
     //std::cout<<(bs[n]->f)==B::f<<std::endl; 
     //should print "true false true" 
    } 
} 

我試圖函數指針bs[n]->f的地址比較反對B::f,但它是不可編譯的。

Demo

我覺得這個問題可能被複制,但我找不到(對不起)。

+0

你想在這裏做什麼?這似乎是[X Y問題](https://meta.stackexchange.com/q/66377/218012) – Justin

+0

@Justin主要是因爲好奇。我想知道是否有可能......對於一些罕見的優化(如果我碰巧需要它)可能會有用。 – cppBeginner

+0

這個問題沒有多大意義;因爲'f'是虛擬的,'bs [n] - > f'總是一個虛擬的調用 –

回答

2

GCC has an extension它允許您獲取虛擬成員函數的地址。

這可以用於像這樣:

#include <vector> 
#include <iostream> 

class B{ 
    public: int aField=0; 
    virtual void f(){}; 
}; 
class C : public B{ 
    public: virtual void f(){aField=5;}; 
}; 
class D: public B{}; 

int main() { 
    B b; 
    C c; 
    D d; 
    std::vector<B*> bs; 
    bs.push_back(&b); 
    bs.push_back(&c); 
    bs.push_back(&d); 
    for(int n=0;n<3;n++){ 
     // This might need to be: (void*) B{}.*&B::f == (void*) (...) 
     std::cout << ((void*) &B::f == (void*)(bs[n]->*&B::f)) << '\n'; 
    } 
} 

Demo

您可能會發現this QA很有趣。

當然,這是非標準的行爲。如果你想在標準C++類似的行爲,你實際上可能會尋找純虛功能:否則

class B{ 
    public: int aField=0; 
    virtual void f() = 0; 
}; 

,你必須有一些其他的機制來溝通,如f()一個bool返回類型。

相關問題