2010-03-02 10 views
17

Jeśli mam następującą deklarację:Czy powinienem usunąć członków string z klasy C++?

#include <iostream> 
#include <string> 

class DEMData 
{ 
private: 
    int bitFldPos; 
    int bytFldPos; 
    std::string byteOrder; 
    std::string desS; 
    std::string engUnit; 
    std::string oTag; 
    std::string valType; 
    int idx; 
public: 
    DEMData(); 
    DEMData(const DEMData &d); 
    void SetIndex(int idx); 
    int GetIndex() const; 
    void SetValType(const char* valType); 
    const char* GetValType() const; 
    void SetOTag(const char* oTag); 
    const char* GetOTag() const; 
    void SetEngUnit(const char* engUnit); 
    const char* GetEngUnit() const; 
    void SetDesS(const char* desS); 
    const char* GetDesS() const; 
    void SetByteOrder(const char* byteOrder); 
    const char* GetByteOrder() const; 
    void SetBytFldPos(int bytFldPos); 
    int GetBytFldPos() const; 
    void SetBitFldPos(int bitFldPos); 
    int GetBitFldPos() const; 
    friend std::ostream &operator<<(std::ostream &stream, DEMData d); 
    bool operator==(const DEMData &d) const; 
    ~DEMData(); 
}; 

co kod powinien być w destruktora? Czy powinienem "usunąć" pola std::string?

+2

Komentarz do stylu: Zamiast zwracania 'const char *' z funkcji, wolałbym zwrócić 'const std :: string &'. Jest to możliwe, gdy zwracany łańcuch jest elementem obiektu. I podobnie dla danych wejściowych, wolałbym 'const std :: string &' –

+2

Czy próbowałeś jeszcze tego przed opublikowaniem pytania? Nie można było usunąć tych łańcuchów, nawet gdybyś chciał. –

+1

Czasami można zobaczyć ludzi nazywających 'clear()' na standardowych kontenerach, zanim wykroczą poza zakres ("usunięcie" w tym sensie). To też nie będzie konieczne. – UncleBens

Odpowiedz

24

Twój destruktor musi jedynie zniszczyć członków, którym przydzielono zasoby. więc nie, nie "usuwaj" ciągów.

usunąć wskazówek przeznaczyć z nowy

Twój destruktor nie musi być więcej niż

~DEMData() 
{ 
} 
+10

w rzeczywistości możesz zostawić ten destruktor na zewnątrz. kompilator zrobi to za ciebie – pm100

+2

Kompilator wygeneruje to dla ciebie, jeśli go nie dostarczysz. – Torlack

6

Nie, elementy std :: string są automatycznie przydzielane do stosu lub sterty i są automatycznie czyszczone. Nie musisz robić nic specjalnego w swoim destruktorze, aby obsłużyć struny.

+1

Na stosie? Tylko jeśli instancja 'DEMData' znajduje się na stosie. –

+1

Ściśle mówiąc, nie można powiedzieć, czy sam obiekt std :: string znajduje się na stosie lub stercie, ponieważ nie wiadomo, w jaki sposób konstruuje się DEMData. Zawarty łańcuch będzie na kupce, chyba że implementacja std :: string używa samego obiektu std :: string do przechowywania ciągu znaków dla krótkich łańcuchów. – Torlack

3

Nie trzeba destruktor (ani konstruktor kopiujący, ani przeciążony operator przypisania). Taki jest sens używania klasy podobnej do ciągi, która robi rzeczy dla ciebie, zamiast używania ciągów w stylu C i ręcznego zarządzania pamięcią.

Kompilator produkuje wszystkie wyżej wymienione dla ciebie i domyślnie destruktor tylko wywołuje destruktory wszystkich członków (dzieje się to niejawnie nawet po zakończeniu destruktora zdefiniowanego przez użytkownika). Destruktor Stringa przejmuje stamtąd.

+0

Myślę, że to powinna być zaakceptowana odpowiedź, ponieważ odpowiada "rzeczy", która przeszkadza OP: > domyślnie destruktor po prostu wywołuje destruktory wszystkich członków (dzieje się to niejawnie nawet po zakończeniu destruktora zdefiniowanego przez użytkownika). – Opher

5

Nie, nie powinieneś usuwać obiektów std::string. zostaną one automatycznie zwolnione po wywołaniu ich destruktora.

Powiązane problemy