2016-04-08 5 views
0

Ich habe diese Objekte rufen wir "MyGroup" s. MyGroup Unterklassen BaseGroup. Da wir ein Echtzeitsystem sind, haben wir nicht den Luxus der dynamischen Speicherzuweisung, also haben wir eine ObjectPool, die eine bestimmte Anzahl von Objekten eines bestimmten Typs zuweist. Also in diesem Fall habe ich 10 MyGroup Objekte zugeordnet."Kann nicht lösen Vorlage basierte Bezeichner X" - Rufen Sie eine Vorlage Parameter Klasse Methode aus Vorlage Klasse (C++)

Jetzt - ich möchte diese Gruppen in einer Schlüssel-Wert-Karte speichern. Also habe ich eine Vorlagenklasse FiniteMap erstellt, um eine generische Karte einer bestimmten Größe zu erstellen, die einen bestimmten Objekttyp speichern kann.

Meine GroupList Klasse Subklassen FiniteMap, noch erlauben Parameter <G, S>, da ich weiß nicht, welche Unterklasse von BaseGroup ich in meiner Grouplist speichern möge.

Die Methode BaseGroup::createGroup() ist rein virtuell, daher ist sie in MyGroup implementiert.

So - das Problem ist, in die Linie mit // *** markiert, ich bin einer der beiden immer in der Zusammenstellung folgt vor: Entweder eine Warnung: Unable to resolve template based identifier createGroup, oder wenn ich rufe tatsächlich die getOrCreateGroup() Methode, einen Fehler: cannot call member function 'virtual MyGroup* MyGroup::createGroup(unsigned int) without object.

Die Grouplist-Objekt wird in Hauptlogik instanziiert:

GroupList<MyGroup, 10> myGroupList; 

Irgendwelche Ideen?

Ich habe diese Template-Klassen:

template <class T, unsigned int S> 
class FiniteMap 
{ 
    // class to implement an array of these types of structures. 
    // Contains methods for put, remove, get, etc. 
    struct Entry 
    { 
     int key; 
     T* pObject; 
     bool inUse; 
     Entry() : key(0), pObject(NULL), inUse(false) {} 
    } 
} 

template <class G, unsigned int S> 
class GroupList : public FiniteMap<G, S> 
{ 
    // ... 
    G* getOrCreateGroup(unsigned int groupNumber) 
    { 
     G* pGroup = this->get(groupNumber); 
     if (pGroup == NULL) 
     { 
      pGroup = G::createGroup(groupNumber); // *** 
      if (pGroup == NULL) 
      { 
      // handle error 
      } 
     } 
     return pGroup; 
    } 
} 

class BaseGroup 
{ 
public: 
    virtual BaseGroup* createGroup(unsigned int groupNumber) = 0; 

protected: 
    unsigned int _groupNumber; 
} 

class MyGroup : BaseGroup 
{ 
public: 
    virtual MyGroup* createGroup(unsigned int groupNumber) 
    { 
     MyGroup* g = MyGroupPool.New(); // Object pool allocation 
     if (g == NULL) 
     { 
      // handle error 
     } 
     else 
     { 
      g->_groupNumber = groupNumber; 
     } 
     return g; 
    } 
} 
+0

Danke, entfernt. – livefree75

+0

Partiell behoben, indem die 'GroupList' Klassendefinition zu: ' Vorlage Klasse GroupList: öffentliche FiniteMap ', und alle' G's zu 'BaseGroup' in ändern 'Gruppenliste'. Aber jetzt bekomme ich, dass ich createGroup() 'ohne ein Objekt nicht aufrufen kann. Aber ich weiß nicht, welche Unterklasse von 'BaseGroup' ich in' getOrCreateGroup' erstellen möchte. – livefree75

Antwort

1

Sie nicht

G::createGroup(); 

weil createGroup nicht statisch nennen kann, ist weder sind Sie von G geerbt.

Meinst du zu machen createGroup statisch? (auch nicht virtuell) Mir ist nicht klar, warum das virtuell ist.

+0

Es ist virtuell, weil ich in der Lage sein möchte, verschiedene Unterklassen von 'BaseGroup' zu erstellen, und jeder muss seinen eigenen Object Pool Allocator verwenden. Daher muss ich 'createGroup' virtuell machen und jede Unterklasse zwingen, sie zu definieren. Ich würde es gerne statisch machen, aber ich bekomme einen Fehler, wenn ich versuche, es virtuell und statisch zu machen. – livefree75

+0

Vergessen zu erwähnen, die 'GroupList' Klasse ist in meiner Hauptlogik instanziiert: ' GroupList myGroupList; ' – livefree75

+0

Das ändert nichts daran, dass Sie keine Instanz von' MyGroup' zum Aufrufen von 'myGroupObject zur Verfügung haben -> createGroup (...) '. Obwohl 'createGroup' nicht von irgendwelchen Mitgliedern abhängig ist, sollten Sie es statisch anstatt virtuell machen – vu1p3n0x

0

Nun, so habe ich das Problem gelöst. Ich bin mir nicht sicher, ob das der beste Weg war oder nicht.

Grundsätzlich habe ich eine createGroup rein virtuelle Methode in GroupList und dann erstellt neue MyGroupList Klasse, die die MyGroup Erstellen von Objekten behandelt.

template <class T, unsigned int S> 
class FiniteMap 
{ 
    // class to implement an array of these types of structures. 
    // Contains methods for put, remove, get, etc. 
    struct Entry 
    { 
     int key; 
     T* pObject; 
     bool inUse; 
     Entry() : key(0), pObject(NULL), inUse(false) {} 
    } 
} 

template <class G, unsigned int S> 
class GroupList : public FiniteMap<G, S> 
{ 
    // ... 
    G* getOrCreateGroup(unsigned int groupNumber) 
    { 
     G* pGroup = this->get(groupNumber); 
     if (pGroup == NULL) 
     { 
      pGroup = G::createGroup(groupNumber); // *** 
      if (pGroup == NULL) 
      { 
      // handle error 
      } 
     } 
     return pGroup; 
    } 

private: 
    virtual G* createGroup(unsigned int groupNumber) = 0; 
} 

template <unsigned int S> 
class MyGroupList : public GroupList<MyGroup, S> 
{ 
public: 
    virtual MyGroup* createGroup(unsigned int groupNumber) 
    { 
     MyGroup* g = MyGroupPool.New(); 
     return g; // may be NULL if unable to allocate 
    } 
} 


class BaseGroup 
{ 
public: 
    // stuff 

protected: 
    unsigned int _groupNumber; 
} 

class MyGroup : BaseGroup 
{ 
public: 
    // some other stuff 
}