2012-04-04 88 views
0

我有一個簡單的問題。我正在編寫C++代碼;我在同一個文件中有兩個類。一個從另一個繼承,我試圖使用模板來使這些類更一般化。C++中的繼承,範圍和模板構造函數

這裏是基類的文件:

template<class E> // this is the class we will execute upon 
class Exec{ 

protected: 

    typedef void (*Exe)(E*); // define a function pointer which acts on our template class. 

    Exe* ThisFunc; // the instance of a pointer function to act on the object 
    E* ThisObj; // the object upon which our pointer function will act 

public: 

    Exec(Exe* func, E* toAct){ThisFunc = func; ThisObj=toAct;} 
    Exec(){;} // empty constructor 

void Execute(){ThisFunc(ThisObj);} // here, we pass our object to the function 

}; 

這裏是繼承類:

template<class E> // this is the class we will execute upon 
class CondExec : protected Exec<E>{ // need the template! 

protected: 

    typedef bool (*Cond)(E*); // a function returning a bool, taking a template class 
    Cond* ThisCondition; 

public: 

CondExec(Exe* func, E* toAct,Cond* condition): Exec<E>(func,toAct){ThisCondition=condition;} 

void ExecuteConditionally(){ 
    if (ThisCondition(ThisObj)){ 
     Execute(); 
     } 
    } 
}; 

然而,當我嘗試,我得到了以下錯誤:

executables.cpp:35: error: expected `)' before ‘*’ token 
executables.cpp: In member function ‘void CondExec<E>::ExecuteConditionally()’: 
executables.cpp:37: error: ‘ThisObj’ was not declared in this scope 
executables.cpp:37: error: there are no arguments to ‘Execute’ that depend on a template    parameter, so a declaration of ‘Execute’ must be available 

看來,執行(即:基地)類沒有得到正確申報;如果我在繼承類中包含typedef和基類的實例變量,我不會收到這些錯誤。但是,如果我包含基類的所有內容,那麼它就毫無意義地使用繼承了!我試過做基類的「聲明」,正如一些人建議的(即:class Base;),但這似乎沒有幫助。

我一直在做這個幾個小時谷歌福;如果任何人有任何想法,那將是超級!

+0

'typename CondExec :: Exe','this-> ThisObj'和'this-> Execute()'。 – 2012-04-04 18:15:11

回答

3

您需要說的是typename Exec<E>::Exe。因爲基類是依賴的。與執行相同,您需要使用前面的基類名稱限定呼叫:Exec<E>::Execute();

否則,這些非限定名忽略從屬基類。

+0

所以你說我在基類中使用的每個實例變量後,我需要用基類名稱來限定類?我想我的困惑是適合限定方法或實例變量的地方 – heisenBug 2012-04-04 18:24:01

+0

@ user1313502:如果類型/變量/函數取決於模板,它需要'Exec ::'(對於類型和函數)或'this- >(用於成員變量)。 – 2012-04-04 18:29:06

+0

@ user1313502是的,這就是我所說的。在查找非限定名稱時,將忽略相關基類。這就增加了更多的安全性,以便當一個依賴基類聲明該名稱的成員時,名稱的含義不會從全局聲明突然變爲基類成員聲明。如果你希望它是一個基類成員,你需要在'BaseClass ::'或'this->'的前面加上適當的名稱。 – 2012-04-04 20:22:38