Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt
-
@john-0 sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Das einzige was direkt geht, ist ein
std::shared_ptr<Base>
im Container abzulegen.Nein, siehe @Finnegan s Antwort.
Ein vector mit unique_ptr entspricht auch eher einem "normalen" vector (dem gehört sein Inhalt auch und shared nichts).
-
@Jockelx sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Nein, siehe @Finnegan s Antwort.
Ja, erwischt schlecht formuliert. „Man muss dann eine der Smart Pointer Klassen von C++ nutzen.“, wäre mit Sicherheit die bessere Wortwahl gewesen.
Was das Thema
unique_ptr
betrifft, man kann keine Kopien erzeugen, was von der Logik an Brilianz für den Entwurf eindeutig nicht zu überbieten ist. Nur hat C++ nicht an Ausdruckskraft durch alle die notwendigen Sprachänderungen gewonnen, die dafür notwendig waren.
-
@john-0 sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
@Jockelx sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Nein, siehe @Finnegan s Antwort.
Ja, erwischt schlecht formuliert. „Man muss dann eine der Smart Pointer Klassen von C++ nutzen.“, wäre mit Sicherheit die bessere Wortwahl gewesen.
Ne, darum geht´s nicht. Der Punkt ist, dass
TMPL<Base>
ein anderer Typ alsTMPL<A>
ist, auch wennA
vonBase
erbt.
-
@john-0 sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Was das Thema
unique_ptr
betrifft, man kann keine Kopien erzeugen, was von der Logik an Brilianz für den Entwurf eindeutig nicht zu überbieten ist. Nur hat C++ nicht an Ausdruckskraft durch alle die notwendigen Sprachänderungen gewonnen, die dafür notwendig waren.Naja, das Problem hast du aber in C#, Java oder sowas auch.
-
@john-0 sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Was das Thema
unique_ptr
betrifft, man kann keine Kopien erzeugen, was von der Logik an Brilianz für den Entwurf eindeutig nicht zu überbieten ist.Man kann durchaus Kopien erzeugen:
std::unique_ptr<int> p = std::make_unique<int>(5); int* zeiger_kopie = p.get(); std::unique_ptr<int> objekt_kopie = std::make_unique<int>(*p);
Was allerdings zurecht schwer gemacht wird, ist zwei besitzende Zeiger (
unique_ptr
) zu erzeugen, die sich um dasselbe Objekt zanken.Das wirkt sich dann natürlich auch auf Container aus, die solche
unique_ptr
halten. Einenstd::vector<std::unique_ptr<int>>
müsste man schon manuell in einenstd::vector<int*>
oder einen anderen Vektor des selben Typs kopieren. Das braucht man meiner Meinung nach aber nur recht selten, und wenn doch, dann halte ich die Wahrscheinlichkeit für recht hoch, dass dann auch ein Vektor mitshared_ptr
gerechtfertigt ist, bei dem das Kopieren kein Problem ist.
-
@rnholzinger01 sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Mein Problem ist, dass man Instanzen von unterschiedlichen Versionen der TMPL-Klasse nicht in einem einzelnen Vector speichern kann.
Naja du kannst immer einen
shared_ptr<void>
nehmen. Damit kannst du alles in den selbenvector
stopfen, ganz egal um welche Klasse es sich handelt. Oder du kannstTMPL
von einer non-template Basisklasse mit virtuellem Destruktor ableiten und dannunique_ptr<DieseNonTemplateBasisklasse>
in denvector
stecken.Oder, falls du nur Zugriff auf
Base
Funktionen brauchst, kannst du einenshared_ptr<Base>
nehmen. Das funktioniert auch wenn das Objekt tatsächlich einTMPL<A>
ist welches nur einA
(und damit einBase
) beinhaltet, aber nicht davon erbt. Dazu gibt es den aliasing-Konstruktor. So kannst du einenshared_ptr<Base>
bekommen der auf das inTMPL<A>
enthalteneA
Objekt zeigt, gleichzeitig aber das ganzeTMPL<A>
am Leben hält.Ansonsten müsste man wissen was du mit den
TMPL<T>
Instanzen in demvector
machen möchtest.
-
@Finnegan sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Man kann durchaus Kopien erzeugen:
Er meinte sicherlich, dass das hier mit den Basiszeigern aber nicht so einfach geht. Oder wie kopierst du da die Objekte (=rufst den richtigen Copy-ctor auf)?
Die Möglichkeit die ich kenne, ist halt eine "clone"-Funktion zu basteln (daher auch der Verweis auf C# & java).
-
@Jockelx sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Die Möglichkeit die ich kenne, ist halt eine "clone"-Funktion zu basteln (daher auch der Verweis auf C# & java).
Du bist so dermaßen eklig!
-
@Swordfish sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Du bist so dermaßen eklig!
Hör auf mit deinen Beleidigungen, das nervt. Schlag lieber eine Alternative vor. Ich verstehe dich nicht. Ein Teil deiner Beiträge ist sachbezogen und gut, der andere Teil irgendwie störend, merkwürdig und nutzlos.
-
@wob sagte in Array/Vector einer Template-Klasse, deren Template-Typ von einer Base Klasse erbt:
Schlag lieber eine Alternative vor.
Das war keine Beleidigung, sondern eine Feststellung. Beobachtbares Verhalten. Aber na schön:
#include <memory> #include <vector> #include <iostream> struct Base { virtual void talk() = 0; virtual ~Base() {}; }; struct A : Base { virtual void talk() override { std::cout << "A\n"; } virtual ~A() { std::cout << "A::d-tor()\n"; } }; struct B : Base { virtual void talk() override { std::cout << "B\n"; } virtual ~B() { std::cout << "B::d-tor()\n"; } }; struct C : Base { virtual void talk() override { std::cout << "C\n"; } virtual ~C() { std::cout << "C::d-tor()\n"; } }; int main() { std::vector<std::shared_ptr<Base>> foo; foo.push_back(std::make_shared<A>()); foo.push_back(std::make_shared<B>()); foo.push_back(std::make_shared<C>()); for (auto const &f : foo) f->talk(); }
Output:
A B C A::d-tor() B::d-tor() C::d-tor()
Aber ich weiß nicht, wieso ich hier das Kindermädchen spielen soll. @hustbaer hat schon alles gesagt.
ach so. kopieren. warum will ich das?
Base *bar{ foo[1].get() }; bar->talk();
*Wirklich* kopieren kann /* edit: */ wenn man den Typ nicht kennt /* edit */ in einer stark typisierten Sprache nur über verrenkungen gehen.