Liste mit Template-Klassen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Hi mir ist bewusst, dass man Template-Klassen nicht direkt in einer Liste speichern kann (mit Liste meine ich hier einen beliebigen STL-Container oder ein Array). Normal geht man ja den Weg über eine abstakte Basisklasse, die alle Interfaces virtuell anbieten und man hält dann eine Liste aus BaseClass-Pointern. Allerdings habe ich das Problem, dass die Methoden als Parameter ebenfalls den Template-Typ nutzen bzw. als Rückgabewert. Dem Aufrufer der Methoden ist jedoch bewusst, um welchen Typ es sich handelt. Die Methoden können bzw. müssen also auch direkt mit dem entsprechenden Template-Parameter aufgerufen werden.

Beispiel:

Code: Alles auswählen

template <typename T>
class MyClass
{
public:
    void setValue(const T &value);
    const T &getValue(void);

private:
    T value;
};

int main(int argc, char *argv[])
{
    std::map<std::string, MyClass*> clslist; // geht natürlich nicht
    clslist["blub"] = new MyClass<int>;

    ...

    clslist["blub"]->setValue<int>(5);

    return 0;
};
So etwas ähnliches möchte ich realisieren. Dabei ist die Performance nicht entscheidend und es können auch einige Wrapper, Functoren, etc eingeführt werden. Ich würde aber gern void-Pointer vermeiden (so eine Lösung habe ich bereits).

Ich vermute fast, dass es keine wirkliche Lösung gibt, aber vielleicht hat ja jemand eine Idee.


Bitte keine Diskussion über schlechtes Design führen, ich muss bestehenden Code verwenden, kann aber den Klassencode auch ändern (wobei ich nicht alles umbauen möchte).

Noch eine Anmerkung: Die Klasse muss auch den Wert (value) vom entsprechenden Typ speichern (von mir aus auch in einem Wrapper oder ähnlichem), daher kann das Template nicht nur auf die Methoden beschränkt sein, sondern die Klasse soll tatsächlich ein Template nutzen oder wenigstens ein konsistenter Typ zwischen Methoden-Signatur und internem Datum bestehen. Gecastet werden darf.
Zuletzt geändert von BeRsErKeR am 26.01.2011, 13:26, insgesamt 1-mal geändert.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Dem Aufrufer der Methoden ist jedoch bewusst, um welchen Typ es sich handelt.
Basisklasse + dynamic_cast?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Und wie würde die Basisklasse aussehen? Einfach leer lassen?

Wäre natürlich toll, wenn man außen nicht unbedingt casten müsste, sondern das ins Interne verschieben könnte.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Irgendwas virtuelles muss sie schon enthalten, damit RTTI zur Verfügung steht (D’tor?). Aber du kannst sie auch leer lassen und static_cast benutzen – das ist dann aber fast dasselbe wie ein void-Zeiger, weil nicht garantiert werden kann, dass die Klasse tatsächlich von dem Typ ist, zu dem gecastet wird.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Stimmt natürlich. Guter Denkanstoß. Man könnte ja dann noch eine Klasse hinzufügen, die die Liste hält und dann Methoden wie

Code: Alles auswählen

template <typename T>
void setValue(const std::string &name, const T &value);

template <typename T>
const T &getValue(const std::string &name);
einfügen, die dann intern den dynamic_cast durchführen und man hat nach außen einfach nur die beiden Template-Methoden.


Wie ist denn das eigentlich wenn die Zwischenklasse nichts virtuelles hat? Also BaseClass -> MyClass -> MyTemplateClass<T>.
Wenn da halt MyClass nix virtuelles hätte (ist nun nicht das Problem da nen virtuellen D'tor einzubauen, aber interessiert mich einfach). Würde dann ein dynamic_cast von BaseClass zu MyTemplateClass<int> trotzdem funktionieren?
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Japp. Wenn du dir aber wirklich sicher bist, dass der Typ stimmt (und sich der Text vielleicht früher schon bewährt hat), benutzt du immer reinterpret_cast, machst die Klasse in Release-Builds komplett leer und setzt ein assert(dynamic_cast<MyClass *>(baseptr)); davor. Dann halten deine Debug-Builds, falls mal was nicht stimmen sollte, und in Release-Builds entfallen die Unkosten.
BeRsErKeR hat geschrieben:Wie ist denn das eigentlich wenn die Zwischenklasse nichts virtuelles hat? Also BaseClass -> MyClass -> MyTemplateClass<T>.
Wenn da halt MyClass nix virtuelles hätte (ist nun nicht das Problem da nen virtuellen D'tor einzubauen, aber interessiert mich einfach). Würde dann ein dynamic_cast von BaseClass zu MyTemplateClass<int> trotzdem funktionieren?
Jede Klasse, die eine Basisklasse mit virtuellen Methoden hat, übernimmt diese. Und wo virtuelle Methoden sind, ist auch Typinformation. (Darum ist eine Optimierung, virtuelle Methoden in der Vererbungshierarchie erst so spät wie möglich einzuführen – natürlich eine der letzten, weil sie im Vergleich zum Aufwand so gut wie nichts bringt.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Krishty hat geschrieben:Japp. Wenn du dir aber wirklich sicher bist, dass der Typ stimmt (und sich der Text vielleicht früher schon bewährt hat), benutzt du immer reinterpret_cast, machst die Klasse in Release-Builds komplett leer und setzt ein assert(dynamic_cast<MyClass *>(baseptr)); davor. Dann halten deine Debug-Builds, falls mal was nicht stimmen sollte, und in Release-Builds entfallen die Unkosten.
Naja wie gesagt spielt die Performance keine große Rolle. Das ist ein sehr kleines Projekt, was ich basteln muss und wird in 3 Wochen keinen mehr interessieren. Wichtig war nur einen Container mit Template-Klassen bereit zu stellen und das ganze möglichst ohne gecaste außenrum, sondern mit relativ einheitlicher Schnittstelle. Und das ist ja nun gegeben. Release-Builds wird es wahrscheinlich eh nicht geben. Das ganze wird getestet und wenn alles richtig läuft ist das schon in Ordnung.
Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Wie ist denn das eigentlich wenn die Zwischenklasse nichts virtuelles hat? Also BaseClass -> MyClass -> MyTemplateClass<T>.
Wenn da halt MyClass nix virtuelles hätte (ist nun nicht das Problem da nen virtuellen D'tor einzubauen, aber interessiert mich einfach). Würde dann ein dynamic_cast von BaseClass zu MyTemplateClass<int> trotzdem funktionieren?
Jede Klasse, die eine Basisklasse mit virtuellen Methoden hat, übernimmt diese. Und wo virtuelle Methoden sind, ist auch Typinformation. (Darum ist eine Optimierung, virtuelle Methoden in der Vererbungshierarchie erst so spät wie möglich einzuführen – natürlich eine der letzten, weil sie im Vergleich zum Aufwand so gut wie nichts bringt.)
Macht Sinn.


Danke für deine Hilfe. ;)
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

BeRsErKeR hat geschrieben:Macht Sinn.
Ergibt einen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Krishty hat geschrieben:
BeRsErKeR hat geschrieben:Macht Sinn.
Ergibt einen.
Das auch.
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Nur das.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Krishty hat geschrieben:Nur das.
Danke für die Deutschstunde. ;) Ich ergebe mich dann mal weiter!
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Wenn sich jemand bei mir bedankt, muss ich eben ganz schnell wieder mein Kharma auf Null kriegen. Und da ich dann schonmal religiös bin, setze ich auch direkt den Absolutheitsanspruch ein.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Das ist doof. Ich hab dir im letzten Post schon wieder gedankt. Nun habe ich Angst was kommt ...
Ohne Input kein Output.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Keine Angst – ich stehe so sehr auf Sarkasmus wie Michelle Rodriguez auf die Pelztasse. Dir sei alles vergeben.

Falls dir das nicht reichen sollte, habe ich aber noch Ablassbriefe im Angebot. Kontodaten per PN.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Schrompf »

Was ist denn eigentlich der Sinn dahinter? Man kann Klassen ja nicht in Containern speichern, weder templates oder normale Klassen. Soll das eine klassische Factory werden, wo man zur Laufzeit bestimmen will, welchen Typ man instanziieren will? In dem Fall sind ja eigentlich auch immer die erzeugten Instanzen miteinander verwandt. Also Ableitungen der selben Basisklasse.

Bevor ich jetzt hier sowas vielfältig Verfügbares wie eine Factory als Codeschnippsel hinschreibe, warte ich doch lieber erstmal auf ne Antwort :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Schrompf hat geschrieben:Man kann Klassen ja nicht in Containern speichern, weder templates oder normale Klassen.
?!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Schrompf »

Ich meine damit: Klassen sind Blaupausen. Die kann man nicht in einer Liste speichern. Was in Containern gespeichert wird, sind Instanzen einer Klasse. Meine Verwirrung stammt daher, dass ich das ursprüngliche Problem nicht verstehe. Zwei Interpretationen:

a) Gemeint sind Instanzen einer Template-Klasse, die man nicht in einem Container speichern kann. Und da ist die erste Grundaussage im Thread bereits falsch: klar kann man die in einen Container hauen. std::list< Klasse<TemplateParam> > und fertig. Das kann die Frage nicht gewesen sein, weil die Lösung zu primitiv ist, um so einen Thread zu rechtfertigen.

b) Gemeint sind wirklich Template-Klassen, z.b. deren Konstruktoren man in einem Container speichern will. Das klang für mich nach dem klassischen Factory Pattern. Das kann die Frage aber auch nicht gewesen sein, denn Factories sind besonders in C++ sehr elegant und einfach umsetzbar - dazu gibt es sicher genügend Informationen im Netz.

Was also ist das Problem? Die Frage habe ich immernoch.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Krishty »

Aaah, verstehe. Klar, da hast du recht.

Das Problem ist, dass der OP Zeiger auf Instanzen einer Template-Klasse mit unterschiedlichen Template-Parametern in einem Container speichern muss. Da das unterschiedliche Typen sind, bräuchte er hier einen heterogenen Container; aber die Zeiger zu konvertieren ist einfacher.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: Liste mit Template-Klassen

Beitrag von Biolunar »

Jetzt hab ich das glaub ich auch verstanden ;) Wie sieht es mit boost::any aus?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von Schrompf »

Ahso, jetzt verstehe ich das. Da wird man in der Tat nicht um Heap-Allokation und eine gemeinsame Basisklasse für alle zu speichernden Instanzen drumrumkommen. Oder tatsächlich boost::any einsetzen. In beiden Fällen muss dann die Information, welcher Typ tatsächlich drinsteckt, von irgendwo anders kommen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Liste mit Template-Klassen

Beitrag von BeRsErKeR »

Es handelt sich hier um eine Art I/O-Port Klasse, die als Schnittstelle zwischen einer Steuerung und einer Simulation dient. Dabei sind diese Port-Klassen so designed, dass man verschiedene Steuersignale und Antworten nutzen kann (bools für States, floats für Geschwindigkeiten, usw). Daher werden dabei Templates genutzt (über das Design will ich mich nicht streiten, das war halt so vorgegeben und ich möchte da nicht groß was dran ändern). Die Schnittstelle zwischen Steuerung und Simulation ist die Gesamtheit aller I/O-Ports, daher würde ich das ganze halt gern in einem Container kapseln, auf den sowohl die Steuerung als auch die Simulation Zugriff haben. Je nach Objekt der Simulationsstrecke werden halt andere Port-Typen (verschiedene Template-Typen) verwendet. Diese konkreten Typen kennt jedoch nur das Objekt bzw. die Steuerung. Die Schnittstelle soll beliebige Typen verwalten können. Da es aber immer Ports sind, die nur einen anderen Typ nutzen, finde ich es schon sinnvoll alle Ports in einer Liste zu speichern und nicht für jeden erdenklichen Port-Typ eine eigene Liste anzulegen. Ja an eine Factory hatte ich auch gedacht, wobei das einen ziemlich großen Aufwand für ein so kleines Projekt bedeutet und prinzipiell hatte ich auch eine Art Factory, die allerdings intern noch mit void-Pointern hantiert hat.

Zum Thema Threadtitel: Ja es ist natürlich keine Liste mit Template-Klassen, sondern eine Liste mit Instanzen von Template-Klassen. ;)
Ohne Input kein Output.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Liste mit Template-Klassen

Beitrag von kimmi »

Ist stimme meinen Vorrednern zu und erkläre das klar für einen Kandidaten für boost::any oder allgemein gesprochen ( wenn du Boost aus irgendwelchen Gründen nicht mehmen darfst ) dem Variant-Pattern.

Gruß Kimmi
Antworten