2014-02-10 105 views
3

我已經搜索了堆棧溢出,但還沒有找到完全解答我的問題的東西。我有一個接口類,其中只包含純虛函數,我希望通過從該類派生的類來實現。從模板類覆蓋純虛函數

我有一個接口,我會打電話給BaseInterface它定義了函數,我想在這個接口派生的所有類中被覆蓋的函數。在這個例子中,假設只有一個純虛函數來實現。我創建了一個名爲的基類,它繼承自BaseInterface併爲繼承的純虛函數添加了一些功能。基地仍然是一個抽象類,因爲它沒有實現BaseInterface中的功能。

我有幾類,從基地這都將受益於基地的常見功能,但指定當toImplement是對他們的情況下運行會發生什麼派生。這些類應該都是具體的,並滿足由BaseInterface設置的所有要求。下面我定義了這些類別之一,稱爲衍生

當BaseInterface和Base沒有模板化時,所有這些都可以正常工作。代碼編譯和運行良好,沒有定義(1.)或實現(2.)到實施基地

但是我想來實現來處理不同類型。根據我的理解,在模板類中有純虛函數是很好的。我模板BaseInterface和某些類型T 基地當我不基地(1),我不能因爲基地編譯定義toImplement不知道tryUsingImplemented使用哪個toImplement。如果我現在將定義添加到基地,代碼預編譯,但鏈接器無法找到Base :: toImplement的實現。最後,如果我在基地(1.和2.)中定義和實現到實施,代碼編譯。

我不喜歡這個,因爲我有一個虛擬實現在實現在基地,我永遠不希望這個實現運行。此外,因爲基地實施實施,派生不再需要實施它。這使得BaseInterface在我眼中無用。

sombody可以告訴我如何執行的實施toImplement衍生,而無需實現它基地第一,如果這是在所有可能的?

template <typename T> 
class BaseInterface { 
    virtual void toImplement(T & t) = 0; 
}; 


template <typename T> 
class Base : public BaseInterface<T> { 
bool m_useImplemented; 

public: 
    explicit Base(bool useImplemented) : m_usedImplemented(useImplemented) {} 

    void tryUsingImplemented(T & t) { 
     if (m_useImplemented) 
     toImplement(t); 
    } 

protected: 
    // 1: Defining toImplement pure virtual function in Base 
    virtual void toImplement(T & t); 
}; 

// 2. Implementing a version of toImplement in Base which does nothing 
template <typename T> 
inline void Base<T>::toImplement(T & t) { 
    // do nothing 
} 

class Derived : public Base<int> { 
public: 
    explicit Derived(bool useImplemented) : Base<int>(useImplemented) {} 

protected: 
    // 3. implementing toImplement in Derived 
    void toImplement(T & t) { 
     std::cout << "Doing stuff for Derived" << std::endl; 
    } 

}; 
+0

您可以提供純虛函數的定義。如果您不希望派生類對'Base :: toImplement'執行非虛擬調用,則將其設爲私有函數。 – Simple

+0

我試圖儘可能簡化我的問題,我確實忘記將BaseInterface :: toImplement定義爲受保護的。這是在原來的代碼,所以問題不是訪問 – user3293204

回答

2

爲了將來的參考,如果您提供了編譯器錯誤消息,這將會很有幫助。

但是,在這種情況下,我知道。您的代碼中有兩處錯誤:

  1. toImplementBaseInterface中的私密。
  2. tryUsingImplemented中的查找不會顯示在基類中。您正面臨着lookup in dependent bases問題。要修復它,請寫this->toImplement(t)
+0

感謝您的回答。我相信這個問題確實在依賴的基礎上查找。我刪除了Base中純虛擬的定義和實現,並將它們的調用替換爲:this-> toImplement,編譯器現在知道使用BaseInterface :: toImplement – user3293204

0

需要聲明toImplementBaseInterfaceprotected如果你打算從一個派生類中調用它。我已經從派生類中刪除了所有重寫方法,並用int取代了Derived::toImplement的參數類型,並且編譯得很好。後者是必要的,因爲Derived不是模板,所以您需要使用傳遞給Base的模板參數。

#include <iostream> 

    template <typename T> 
    class BaseInterface { 
    protected: 
    virtual void toImplement(T & t) = 0; 
    }; 


    template <typename T> 
    class Base : public BaseInterface<T> { 
    bool m_useImplemented; 

    public: 
    explicit Base(bool useImplemented) : m_useImplemented(useImplemented) {} 

    void tryUsingImplemented(T & t) { 
     if (m_useImplemented) 
      toImplement(t); 
    } 
    }; 

    class Derived : public Base<int> { 
    public: 
    explicit Derived(bool useImplemented) : Base<int>(useImplemented) {} 

    protected: 
    // 3. implementing toImplement in Derived 
    void toImplement(int & t) { 
     std::cout << "Doing stuff for Derived" << std::endl; 
    } 

    }; 
+0

感謝您的答案!我忘了將保護關鍵字添加到BaseInterface中,但它在我的原始代碼中,所以這不是問題。問題在於調用在Base中的實現,其中編譯器不知道要實現依賴於模板T.通過使用this-> toImplement – user3293204

+0

修復了這個問題。但是,仍然很高興知道這個問題。 –