2012-04-04 12 views
0

Ich habe eine kurze Frage. Ich schreibe C++ - Code; Ich habe zwei Klassen in der gleichen Datei. Die eine erbt von der anderen, und ich versuche, Vorlagen zu verwenden, um die Klassen allgemeiner zu machen. HierVererbung, Bereich und Vorlage Konstruktoren in C++

ist die Datei für die Basisklasse:

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 

}; 

Und hier ist die geerbte Klasse:

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(); 
     } 
    } 
}; 

Allerdings, wenn ich dies versuchen, erhalte ich die folgenden Fehler:

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 

Es scheint, dass die Exec (dh die Basis) -Klasse nicht ordnungsgemäß deklariert wird; Wenn ich typedef und die Instanzvariablen aus der Basisklasse in die geerbte Klasse einbeziehe, erhalte ich diese Fehler nicht. Wenn ich jedoch alles aus der Basisklasse einschließe, ist es sinnlos, die Vererbung zu verwenden!

Ich habe versucht, eine "Deklaration" der Basisklasse, wie einige empfohlen haben (dh: Klasse Base;), aber das scheint nicht zu helfen.

Ich habe einige google-fu für einige Stunden gemacht; Wenn jemand Ideen hat, wäre das super!

+0

'Typenname CondExec :: Exe',' this-> ThisObj' und 'this-> Execute()'. –

Antwort

3

Sie müssen typename Exec<E>::Exe sagen. Weil die Basisklasse abhängig ist. Das Gleiche gilt für Execute. Sie müssen den Aufruf mit dem Namen der Basisklasse voranstellen: Exec<E>::Execute();.

Andernfalls ignorieren diese nicht qualifizierten Namen die abhängige Basisklasse.

+0

Sie sagen also nach jeder Instanzvariable, die ich in der Basisklasse verwende, muss ich die Klasse mit dem Basisklassennamen qualifizieren? Ich denke, meine Verwirrung ist, wo es angebracht ist, Methoden oder Instanzvariablen zu qualifizieren – heisenBug

+0

@ user1313502: Wenn der Typ/Variable/Funktion von der Vorlage abhängt, benötigt es entweder 'Exec :: '(für Typen und Funktionen) oder' this- > '(für Mitgliedsvariablen). –

+0

@ user1313502 ja das ist was ich sage. Abhängige Basisklassen werden ignoriert, wenn nach unqualifizierten Namen gesucht wird. Das bedeutet mehr Sicherheit, sodass, wenn eine abhängige Basisklasse ein Mitglied dieses Namens deklariert, die Bedeutung des Namens sich nicht plötzlich von einer globalen Deklaration zu einer Basisklassenmitgliedsdeklaration ändert. Wenn Sie möchten, dass es sich um ein Basisklassenmitglied handelt, müssen Sie den Namen entsprechend mit 'BaseClass ::' oder 'this->' versehen. –