2012-12-12 28 views
0

可能重複:
C++: Accessing Virtual Methods不同的方法來調用虛方法

我試圖使用虛擬方法表的索引 類調​​用函數...假設我們有以下代碼:

class Base 
{ 
public: 
    Base() {} 
    virtual ~Base() {} 

    virtual Base* call_func(unsigned int func_number) 
    { 
     // Some way to call f_n 
    } 
protected: 
    virtual Base* f_1() const = 0; 
    virtual Base* f_2() const = 0; 
    virtual Base* f_3() const = 0; 
}; 

我已經實現了這個使用樂趣ction數組,if語句 和case-statement ...所以,是否有更好的方法來調用方法 只使用指針(例如訪問vtable)或類似的東西?

決心在此之後我要去創建派生類(例如derived1和衍生2) 與F_1,F_2,F_3的不同的實現並具有一類控制是這樣的:

class Control 
{ 
protected: 
    Base* current; 

public: 
    Control(Base* curr = new derived1): current(curr) {} 
    virtual ~Control() 
    { 
     delete current; 
    } 
    virtual void call_functions(unsigned int func_numb) 
    { 
     delete current 
     Base* new = current->call_func(func_numb); 
     current = new; 
    } 
}; 

對不起我可怕的英語:S ...並提前致謝!

+0

但是爲什麼?有意義的名字有一些東西。 –

+0

這是一種功課嗎?這個問題與[幾分鐘前發佈的內容]有着驚人的相似性(http://stackoverflow.com/questions/13841248/c-accessing-virtual-methods) – juanchopanza

回答

0

使用指針的成員函數:

virtual Base* call_func(Base *(Base::*pf)()) 
{ 
    return this->*pf(); 
} 

如果您需要的參數是一個算術標,使用查找數組:

virtual Base* call_func(unsigned int func_number) 
{ 
    static const Base *(Base::*(table[]))() = { &Base::f_1, &Base::f_2, &Base::f_3 }; 
    return this->*(table[func_number])(); 
} 
0

只是一個粗略的代碼。

void *vptr = *(void**)this; 
void *method = ((void**)vptr)[index + first_method_offset]; 
typedef void (*method_type)(); 
void *m = (method_type)method; 
m(); 

其中first_method_offset是需要的,如果您的索引方法不是第一個在vtable中。

1

C++沒有非常好的內置內省,也就是說,您可能知道,您不能在運行時按名稱查找成員函數,並從命名查找中調用它。但是你可以創建一個成員函數指針表;例如,請參閱C++ FAQ Lite條目How do I create and use an array of pointer-to-member-function?中的示例。 (我希望這與你已經提到的「函數陣列」不一樣,但它似乎是實現你想要的最好方法。)

如果我可能會問,爲什麼你需要調用函數按指數?虛擬功能通常存在以用它們自己的任務參數完成特定的任務。

如果你要更直接地訪問vtable,你可能會做一些工作,但它會變得脆弱和不可移植。

+0

是的,你說得對,我會把你的最後一段作爲我的問題的一個很好的答案 – user1760216

相關問題