2011-04-18 122 views
0

我有一個看起來像這樣一個層次結構:非虛擬接口 - 如何調用正確的虛擬功能

class Base 
{ 
public: 
    void Execute(); 
    virtual void DoSomething() = 0; 
private: 
    virtual void exec_(); 
}; 

class Derived : public Base 
{ 
public: 
    //DoSomething is implementation specific for classes Derived from Base 
    void DoSomething(); 

private: 
    void exec_(); 
}; 

void Base::Execute() 
{ 
    // do some work 
    exec_(); //work specific for derived impl 
    // do some other work 
} 

void Derived::DoSomething() 
{ 
    //impl dependent so it can only be virtual in Base 
} 


int main() 
{ 
    Derived d; 
    Base& b = d; 

    b.Execute(); //linker error cause Derived has no Execute() function?? 

} 

所以,問題是我怎麼叫使用這種模式執行()當我創建一個派生使用我的基類。在我的情況下,我不想直接創建Derived,因爲我有從Base派生的多個類,根據某些條件我必須選擇不同的派生類。

任何人都可以幫忙嗎?

+0

有人請編輯nvi的標籤wiki,謝謝。 – 2011-04-18 09:04:17

+0

嗯,什麼是'nvi'? – 2011-04-18 09:05:13

+0

@Konrad:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface – 2011-04-18 09:05:45

回答

6

class Base 
{ 
public: 
    void Execute(); 
private: 
    virtual void exec_() {} 
}; 

class Derived : public Base 
{ 
private: 
    void exec_() {} 
}; 

void Base::Execute() 
{ 
    // do some work 
    exec_(); //work specific for derived impl 
    // do some other work 
} 

int main() 
{ 
    Derived d; 
    Base& b = d; 

    b.Execute(); 
} 

編譯,鏈接,和我運行。

+0

模糊不清,但DoSomething是重要的,但不知道你是否爲了簡潔或因爲它在那裏是錯的而丟掉了它? – 2011-04-18 09:12:27

+0

我沒有見過'Base :: Execute'的實現。 +1給你,這個問題比我想象的更加微不足道。 – 2011-04-18 09:13:41

+1

@Tony:DoSomething與您的問題無關,因爲它根本不遵循NVI原則。 – 2011-04-18 09:14:08

0

您應該也可能在您的基類中創建exec_()純虛擬。然後您還需要在派生類中實現它。

0

您需要爲exec_()函數編寫函數定義。