Seite 1 von 1
Template mit später deklarierter Klasse
Verfasst: Fr Nov 26, 2010 12:22 pm
von Xin
Moin, mal was für die C++-Spezialisten.
Da ich einen ganzen Stapel Klassen habe, die austauschbar sein müssen und sich ähnlich verhalten sollen, dabei aber gleichzeitig nicht Namensräume vollmüllen sollen, möchte ich Unterklassen im Namensraum der Oberklasse haben.
Code: Alles auswählen
class StandardData
{
int a;
};
template< typename DataType >
class Interface
{
virtual bool func( DataType & bla ) = 0;
bool func( DataInterface & bla ) { ... } // ruft func( DataType ), falls richtiger Typ
};
class Element;
class Element::Data; // Fehler C2027: "Verwendung des undefinierten Typs "Element"
class Element : public Interface< class Element::Data >
{
class Data : public StandardData
{
int b;
}
bool func( Data & myData );
};
Von den Element-Klassen werde ich eine ganze Reihe haben, ich möchte den Aufbau soweit wie möglich standardisieren, habe aber nun das Problem, dass ich Element nicht von Adapter< Element::Data > ableiten kann, weil Element::Data noch nicht deklariert ist.
Hat jemand eine Idee, wie ich das formulieren kann, so dass Visual C mich versteht?
Wie kann ich eine Klasse innerhalb des Namensraum der Klasse deklarieren, bevor diese Klasse definiert wurde?
Re: Template mit später deklarierter Klasse
Verfasst: Fr Nov 26, 2010 7:05 pm
von AnGaiNoR
Xin hat geschrieben:Wie kann ich eine Klasse innerhalb des Namensraum der Klasse deklarieren, bevor diese Klasse definiert wurde?
Gar nicht, das gibt C++ nicht her.
EDIT:
Solange es keinen wirklichen Grund dagegen gibt, könntest du aber die Data-Klasse einfach aus der Element-Klasse herausholen, und schon hätte sich das Problem erledigt.
Re: Template mit später deklarierter Klasse
Verfasst: Fr Nov 26, 2010 7:33 pm
von Xin
AnGaiNoR hat geschrieben:Xin hat geschrieben:Wie kann ich eine Klasse innerhalb des Namensraum der Klasse deklarieren, bevor diese Klasse definiert wurde?
Gar nicht, das gibt C++ nicht her.
Sieht so aus. Aber ich weiß auch nicht alles, also kann man ja mal nachfragen, ob jemand noch Ideen hat.
AnGaiNoR hat geschrieben:EDIT:
Solange es keinen wirklichen Grund dagegen gibt, könntest du aber die Data-Klasse einfach aus der Element-Klasse herausholen, und schon hätte sich das Problem erledigt.
Ich habe kein Problem damit, das ganze funktionierend zu formulieren - ich hätte die Datenklassen allerdings gerne innerhalb der Element-Klassen, weil das jeweilige Element der Einzige ist, der die Klasse wirklich genau kennen muss.
Re: Template mit später deklarierter Klasse
Verfasst: Fr Nov 26, 2010 7:36 pm
von AnGaiNoR
Xin hat geschrieben:
Ich habe kein Problem damit, das ganze funktionierend zu formulieren - ich hätte die Datenklassen allerdings gerne innerhalb der Element-Klassen, weil das jeweilige Element der Einzige ist, der die Klasse wirklich genau kennen muss.
Deshalb würde es ja auch keinen Sinn ergeben, die Datenklasse außerhalb der Elementklasse zu definieren, denn dann wäre sie ja eigentlich gar nicht mehr privat.

Re: Template mit später deklarierter Klasse
Verfasst: Fr Nov 26, 2010 7:52 pm
von AnGaiNoR
Mir ist eine "Lösung" eingefallen, aber die finde ich selbst schon nicht sonderlich gut...
Code: Alles auswählen
// Templateklasse für Daten
template< class ElementClass > class Data;
// Datenklasse für Klasse "Element"
class Element;
template< > class Data< Element >;
// Elementklasse
class Element : Interface< Data< Element > >
{
};
Re: Template mit später deklarierter Klasse
Verfasst: Sa Nov 27, 2010 2:37 pm
von Kerli
Eine andere Ansatz das ganze anzugehen wäre mit Policies in etwa so:
Code: Alles auswählen
class DataInterface;
class StandardData
{
int a;
};
template< typename DataType >
class Interface
{
public:
virtual bool func( DataType & bla ) = 0;
bool func( DataInterface & bla ) {} // ruft func( DataType ), falls richtiger Typ
};
class ElementDefaultPolicy
{
public:
class Data : public StandardData
{
int c;
};
bool func(Data& myData) {}
};
class ElementSpecialPolicy
{
public:
class Data : public StandardData
{
char special[10];
};
bool func(Data& myData) {}
};
template<class Policy>
class Element : public Policy, public Interface<typename Policy::Data>
{
public:
bool func(typename Policy::Data& myData)
{
return Policy::func(myData);
}
};
int main()
{
Element<ElementDefaultPolicy> test;
Element<ElementSpecialPolicy> another;
return 0;
}
Dabei musst du für jeden neuen Elemet Typ nur einen neue Policy-Klasse anlegen.