std::shared_ptr und dynamische Arrays



  • camper schrieb:

    Ki schrieb:

    Aber gibt es auch Programmiertechnische Maßnahmen, um zu verhindern, dass Basisklassenzeiger überhaupt angelegt werden können?

    private Vererbung

    Dann könnte ich auch gleich wieder eine Aggregation nehmen und alle Methoden durchreichen.


  • Mod

    Ki schrieb:

    camper schrieb:

    Ki schrieb:

    Aber gibt es auch Programmiertechnische Maßnahmen, um zu verhindern, dass Basisklassenzeiger überhaupt angelegt werden können?

    private Vererbung

    Dann könnte ich auch gleich wieder eine Aggregation nehmen und alle Methoden durchreichen.

    oder einfach using-Deklarationen verwenden



  • camper schrieb:

    Ki schrieb:

    camper schrieb:

    Ki schrieb:

    Aber gibt es auch Programmiertechnische Maßnahmen, um zu verhindern, dass Basisklassenzeiger überhaupt angelegt werden können?

    private Vererbung

    Dann könnte ich auch gleich wieder eine Aggregation nehmen und alle Methoden durchreichen.

    oder einfach using-Deklarationen verwenden

    Oh 😃 Gut, DAS ist ein toller Einwand, danke 🙂



  • knivil schrieb:

    Okay, dann formuliere ich es als Frage: Wird bei std::vector<int>(k) jedes Element auf 0 gesetzt?
    Passiert das auch bei new int[k]? Was passiert bei char? Und was muss ich tun, um rohen Speicher zu erhalten (im Gegensatz zu new char[...])?

    In allen Fällen wird der Skalar nicht initialisiert, denn alle Elemente werden default-initialized , was bei Skalaren bedeutet dass nichts geschieht. Genauso bekommst du auch rohen Speicher. Denn wenn du ein Array von Skalaren hast, dann werden diese (solange du keinen Initializer im Deklarator hast) default-initialized.
    (Willst du hingegen, dass jedes Element value-initialized wird, dann schreibst du new char[...]() , siehe auch §8.5/11).

    Im Standard ist das ganze folgendermaßen zu deduzierenn.

    N3690 §8.5/11 schrieb:

    If no initializer is specified for an object, the object is default-initialized.

    Für Arrays heißt das:

    N3690 §8.5/7 schrieb:

    To default-initialize an object of type T means:
    — if T is an array type, each element is default-initialized;

    Und für Skalare heißt das:

    To default-initialize an object of type T means:
    — otherwise [(Die beiden anderen Stichpunkte sind für Klassen und Arrays)], no initialization is performed.

    Bei vector geht das eine ganze Weile so, bis man wieder bei new ankommt. Da bei default-insertion keine Parameter an std::allocator::construct mitgegeben werden, wird es value-initialized*.

    *Dank der Syntax die der Standard für den Aufruf von new festlegt.



  • Sone schrieb:

    Bei vector geht das eine ganze Weile so, bis man wieder bei new ankommt. Da bei default-insertion keine Parameter an std::allocator::construct mitgegeben werden, wird es default-initialized.

    Knapp dabei ist auch daneben.



  • vaterundsohn schrieb:

    Sone schrieb:

    Bei vector geht das eine ganze Weile so, bis man wieder bei new ankommt. Da bei default-insertion keine Parameter an std::allocator::construct mitgegeben werden, wird es default-initialized.

    Knapp dabei ist auch daneben.

    ::new ((void*)c) C(forward<Args>(args)...)
    

    Oh, du hast Recht. Die Klammer bleibt bestehen... mein Fehler. Dann ist es value-initialization, und es wird zero-initialized (da Skalar)...



  • Also wird bei std::vector zero-initialized und bei new default-initialized?



  • knivil schrieb:

    Also wird bei std::vector zero-initialized und bei new default-initialized?

    Bei vector<int> ja. Allgemein wird bei vector value-initialized (was bei ints zero bedeutet) und bei new default-initialized.

    Das ist aber kein Grund new statt vector zu verwenden, vector.reserve() hat mir bis jetzt immer ausgereicht.*

    * Gut, letztens hatte ich mir eine memchunk-Klasse geschrieben, die mir einige Gigabyte virtuellen Memory allokiert, der dann von ihr verwaltet wird. In dem Fall habe ich auf new + std::unique_ptr<char*> + Verwaltungsdaten zurückgegriffen, weil ein vector falsche Semantik gehabt hätte.



  • Siehste ... und wenn ich Bilddaten verarbeite, dann moechte ich mir auch gern die Initialisierung sparen, da sowieso sofort was anderes reingeschrieben wird. Normalerweise brauche ich auch kein push_back, reserve, ...



  • knivil schrieb:

    Siehste ... und wenn ich Bilddaten verarbeite, dann moechte ich mir auch gern die Initialisierung sparen, da sowieso sofort was anderes reingeschrieben wird. Normalerweise brauche ich auch kein push_back, reserve, ...

    Bei Bilddaten wäre vector+reserve+push_back aber angebracht, weil dann hast du gleich Move- und Kopiersemantik.

    Meine Klasse hat garantiert, dass ein Pointer nie invalidiert wird, das braucht man bei Bildern eher nicht.


Anmelden zum Antworten