Hoi zäme,
ich habe eine Übungsaufgabe und merke, ich kann mir die dahinter
liegende Frage nicht beantworten.
D.h. ich frage hier nicht in dem Sinne "Gebt mir die Lösung zur Aufgabe"
sondern ich suche Hilfe, die dahinter liegende Frage zu beantworten.
>Zur Aufgabe:
Es gibt eine Klasse, die einen Vector von Zeigern hat.
Aufgabe ist, den Typ und betroffennen Code so an zu passen, dass die
Klasse der ausschhließliche Owner der Instanzen ist, welche die Elemente
des Vectors referenziern.
1
classMyClass
2
{
3
private:
4
vector<ToBeOwned*>toBeOwnedInstances;
5
}
>Wo sich meine Gedanken drum kreisen:
Wegen der Anforderung "ausschließlich" wird es ein unique_ptr.
Ich farge mich jetzt,
A)
wenn ich einen Vector von unique_ptr´s mache, gehören dann die Instanzen
technisch gesehen nicht dem Vector und eben nicht MyClass?
B)
Oder gehört die Instanz des Vectors MyClass, weil es ein Memeber von
MyClass ist und damit gehört MyClass auch die Instanzen im Vector?
C)
Im Prinzip könnte man auch machen
unique_ptr<vector<unique_ptr<T>>
Das würde (glaube ich) nur Sinn ergeben, wenn man den Vector zwischen
verschiedenen Klassen rumreichen und dabei die Ownership und Lifetime
geklärt haben möchte
Grüssli !
Das ist eine ziemlich philosophische Frage. Wenn man die penibel
beantworten möchte muss man sich genau anschauen was die jeweilige
Lehrperson unter "Owner" versteht, pauschal kann man das nicht sagen.
Praktisch betrachtet ist vector<unique_ptr<ToBeOwned>> schon genau
richtig, so macht man das.
Daniel Larusso schrieb:> unique_ptr<vector<unique_ptr>>
Ist so semi sinnvoll, denn die vector Klasse ist klein, die kann man
besser direkt instanzieren.
Daniel Larusso schrieb:> wenn man den Vector zwischen verschiedenen Klassen rumreichen und dabei> die Ownership und Lifetime geklärt haben möchte
Dazu kann man auch eine direkte Instanz nehmen und die mit "move"
jeweils verschieben, oder einfach Referenzen darauf herumreichen.
Daniel Larusso schrieb:> Wegen der Anforderung "ausschließlich" wird es ein unique_ptr.> Ich farge mich jetzt,> A)> wenn ich einen Vector von unique_ptr´s mache, gehören dann die Instanzen> technisch gesehen nicht dem Vector und eben nicht MyClass?
Die Frage ist genau richtig, und nicht philosophisch. Denn die Instanz
gehört tatsächlich dem einzelnen unique_ptr im Vector, und nicht dem
Vector und auch nicht der Klasse.
Was zur Folge hat, daß man die „Instanz“ dort herausholen und die
Ownership übertragen kann. Damit würde ohne weitere Vorkehrungen die
Aufgabenbedingung „ausschließlich“ nicht erfüllt.
Oliver
Oliver S. schrieb:> Was zur Folge hat, daß man die „Instanz“ dort herausholen und die> Ownership übertragen kann.
Da der Vector ein "private Member" von MyClass ist, kann man das nur
über Methoden eben dieser Klasse. Ich sehe die Bedingung als erfüllt an.
Richtig ist: std::vector<std::unique_ptr<T>>
Der std::vector<> ist ein privates Datenelement der Klasse, ist also
eine Komposition. Der std::vector<> ist also nur ein technisches
Hilfsmittel,
um die 1-* Beziehung auszudrücken.
Ich könnte mir vorstellen, dass es weitere Aufgabeteile gibt, die auf
das Hinzufügen bzw. Entfernen von std::unique_ptr<> zum/vom vector
abzielen.
Das korrekt zu implementieren ist aber gar nicht so einfach,
insbesondere wenn man auch move & copy implementieren möchte und das
ganze dann auch Exception-Sicher sein soll. Im Prinzip müsste man den
ganzen Code vom std::vector kopieren.
Das ist sicher kaum sinnvoll und führt den Zweck von Klassen wie
std::vector und Code-Wiederverwendbarkeit ad absurdum. Der Sinn von
std::vector ist natürlich, es so zu machen wie schon vorgeschlagen, also
"std::vector<std::unique_ptr<ToBeOwned>>".
Philosophisch könnte man sagen dass die ToBeOwned-Instanzen dem
unique_ptr gehören, welche wiederum dem vector gehören, die wiederum
MyClass gehören, was also die Aufgabenstellung (je nach Definition)
nicht erfüllt. Das ist aber IMO keine besonders sinnvolle
Betrachtungsweise. Aber im akademischen Umfeld gibt es ja gelegentlich
ziemlich skurrile Vorstellungen...
Oliver S. schrieb:> Was zur Folge hat, daß man die „Instanz“ dort herausholen und die> Ownership übertragen kann.
Ok, da hätte ich gesagt, wenn man das mit Vorsatz machen will, kann man
sich über .get() immer ein Bein stellen.
Wobei ich mir auch die Frage stelle, was passiert, wenn man irgendein
Element ::move´d... klingt ungesund :>
Daniel Larusso schrieb:> Wobei ich mir auch die Frage stelle, was passiert, wenn man irgendein> Element ::move´d... klingt ungesund :>
Das geht an sich schon; man darf danach mit dem Element halt nichts mehr
machen, außer es zu zerstören (Destruktor-Aufruf).
Manche Klassen können zusätzlich eine Garantie bieten dass sie nach dem
"move" in irgendeinen Leer-Zustand gehen und dann weiter genutzt werden
können, bei std::vector ist das aber nicht der Fall.