Forum: PC-Programmierung C++17 / unique_prt / vectors


von Daniel Larusso (Gast)


Lesenswert?

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
class MyClass
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 !

von Programmierer (Gast)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

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

: Bearbeitet durch User
von Zombie (Gast)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Programmierer (Gast)


Lesenswert?

Man könnte die Fragestellung auch so verstehen, dass MyClass praktisch 
std::vector nachimplementieren soll, also so in der Art:
1
class MyClass {
2
  MyClass () : toBeOwnedInstances (new ToBeOwned [...]), count (...) {}
3
  ~MyClass () { delete [] toBeOwnedInstances; }
4
  ...
5
private:
6
  ToBeOwned* toBeOwnedInstances;
7
  std::size_t count;
8
}

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...

von Daniel Larusso (Gast)


Lesenswert?

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 :>

von Programmierer (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.