Initialisierung im Konstruktor vor Zuweisung



  • Hallo!

    In einem Clone einer String Klasse befinden sich einige Überladungen der Konstruktoren:

    class MyString
    {
    private:
      char  *m_pStr  
      size_t m_size;
    
    // Code...
    
    public:
    
    // Standardkonstruktor
    MyString()
      : m_pStr(0), m_size(0)
    {}
    
    // Konstruktor 2
    MyString(const size_t &size)
      : m_pStr(0), m_size(size)
    {
      _new(m_size);
    }
    
    // Konstruktor 3
    MyString(const char *pStr)
      : m_pStr(0), m_size(0)
    {
      m_size = strlen(pStr);
      _new(pStr);
    }
    
    //Code...
    };
    

    Ist es sinnvoll Konstruktor 2, 3 zu initialisieren bzw. bei 2 m_pStr mit 0 zu belegen oder ist das Schwachsinn und schlechter Stil?

    P.S.: In Funktion _new(typ) wird zuerst immer überprüft:

    if (m_pStr != 0)
      _free();
    //...
    

    m_pStr ist doch nicht von vorn herien mit 0 initialisiert, oder?



  • HaJo. schrieb:

    m_pStr ist doch nicht von vorn herien mit 0 initialisiert, oder?

    Das ist korrekt.



  • Verstehe das Problem nicht. Verstehe nicht, was einmal in Konstruktor 2 das

    _new(m_size);
    

    und in Konstruktor 3 das

    _new(pStr);
    

    machen soll. Verstehe auch nicht was der simple Aufruf

    _free();
    

    zur Folge haben soll. Sind wahrscheinlich Methoden, die da fehlen ?!

    Aber wenn Du einfach nur fragen wolltest, ob es sinnvoll ist, die Member-Variablen direkt über ihren eigenen Konstruktor zu Initialisieren, anstatt ihnen erst im Konstruktor-Block von MyString den richtigen Wert zuzuweisen, dann läßt sich dies prinzipiell mit ja beantworten, zumindestens auch nicht verneien, wenn man kein bischen Geschwindigkeit verschwenden will und es auch so machbar ist. Mit machbar meine ich z.B., dass man dann auch die Variable m_size vor m_pStr deklariert sein sollte, damit man auch im Konstruktor 3 m_size zuerst initialisieren kann. Dann kann man nämlich für die folgende Initialisierung von m_pStr den Wert von m_size für die ausreichend große Speicherreservierung bereits verwenden und muss nicht ein 2. mal die Funktion strlen aufrufen.

    Persönlich bin ich aber der Meinung, dass man lieber Wert auf lesbaren Code legen sollte, denn der Geschwindigkeitsgewinn bei der Initialisierung atomaren Typen (wie int oder Pointer auf irgend etwas) eher von theoretischer Natur. Natürlich sollte man dann aber auch bei der Initialisierung im Konstruktor-Block erst recht mit einem Aufruf von strlen auskommen.

    Gruß,
    Sven



  • wischmop2 schrieb:

    Verstehe das Problem nicht. Verstehe nicht, was einmal in Konstruktor 2 das

    _new(m_size);
    

    und in Konstruktor 3 das

    _new(pStr);
    

    machen soll. Verstehe auch nicht was der simple Aufruf

    _free();
    

    zur Folge haben soll. Sind wahrscheinlich Methoden, die da fehlen ?!

    Richtig. Das sind Methoden der Klasse. Die Methode _new(typ) ist überladen und kann somit Speicher (Bytes) alloziieren oder einen const char* kopieren.

    wischmop2 schrieb:

    Aber wenn Du einfach nur fragen wolltest, ob es sinnvoll ist, die Member-Variablen direkt über ihren eigenen Konstruktor zu Initialisieren, anstatt ihnen erst im Konstruktor-Block von MyString den richtigen Wert zuzuweisen, dann läßt sich dies prinzipiell mit ja beantworten, zumindestens auch nicht verneien, wenn man kein bischen Geschwindigkeit verschwenden will und es auch so machbar ist. Mit machbar meine ich z.B., dass man dann auch die Variable m_size vor m_pStr deklariert sein sollte, damit man auch im Konstruktor 3 m_size zuerst initialisieren kann. Dann kann man nämlich für die folgende Initialisierung von m_pStr den Wert von m_size für die ausreichend große Speicherreservierung bereits verwenden und muss nicht ein 2. mal die Funktion strlen aufrufen.

    Persönlich bin ich aber der Meinung, dass man lieber Wert auf lesbaren Code legen sollte, denn der Geschwindigkeitsgewinn bei der Initialisierung atomaren Typen (wie int oder Pointer auf irgend etwas) eher von theoretischer Natur. Natürlich sollte man dann aber auch bei der Initialisierung im Konstruktor-Block erst recht mit einem Aufruf von strlen auskommen.

    Gruß,
    Sven

    Also meine Frage war eigentlich: Ob ich die Membervariablen in einem Konstruktor mit Parametern initialisieren muss/sollte. Das hat sich jetzt aber geklärt, da ich das nun definitiv tue. Und zwar den char Zeiger IMMER mit 0 und m_size mit 0 oder ggf. mit dem übergebenem "Längenwert".



  • Also ich verstehe dein Problem so: Du fragst, ob du das Char-Array erst auf Null initialisieren sollst um es dann im Rumpf des Konstruktors zu erstellen.(?)

    Wenn dir die größe des Arrays bekannt ist, kannst du das Array bereits im Rumpf erstellen, z.B.:

    MyString( const size_t &size )
    : m_size( size ),
      m_pStr( new char[size] )
    {}
    

    Man sollte immer soviel initialisieren, wie möglich und alles andere im Rumpf zuweisen (meistens).


Anmelden zum Antworten