Подскажите есть ли правила хорошего тона или общепринятые соглашения по управлению динамической памятью в C++.
Например есть класс
class SomeData {
private:
char* internalString_;
public:
SomeData(char * internalString);
}
Как правильно реализовать конструктор? Класс должен сам выделить память и скопировать в нее строку?
SomeData::SomeData( char* internalString ) {
internalString_ = new char[strlen(internalString)+1];
*internalString_ = '\0';
strcpy( internalString_, internalString);
}
Или можно оставить выделение памяти за тем кто вызывает конструктор? Вот так:
SomeData::SomeData( char* internalString ) {
internalString_ = internalString;
}
И что делать если это будет не строка а более сложный объект, которые еще как то инициализировать необходимо?
Если можно и так и так, то в каких случаях какой политики придерживаться?
Смотрите - если выделяет кто-то другой, то кто должен освобождать память? Если деструктор - то вы не защищены от того, чтоб не передать случайно адрес массива. Если самостоятельно - надо отслеживать, что все объекты уже уничтожены, и не забыть освободить.
Поэтому в общем случае (исключения, подтверждающие правило, всегда возможны) используется идиома RAII - захват ресурса есть инициализация (а деструкция - освобождение).
Так что в общем случае забирайте ресурсы в конструкторе, а освобождайте в деструкторе.
В общем, если у вас в классе есть указатель или ссылька, то в обязательном порядке определите деструктор(освобождать память), конструктор копирования(копировать не указатель, а обьект, на который указывает он), оператор присваивания(присвоить указатель или обьект?...)... Если хотите придерживаться правилам хорошего тона. И ваш класс как минимум будет выглядеть так:
class SomeData {
private:
char* internalString_;
public:
SomeData(char * internalString);
SomeData(const SomeData&);
SomeData& operator =(const SomeData&);
~SomeData() { delete [] internalString_; }
};
А вот в первом определении вашего конструктора наблюдаю ошибку:
*internalString_ = '\0';
Зачем первому сиволу присваивать символ конца строки?... Просто убрать эту строку
А еще лучше вместо указателей хранить умный указатель, или, для вашего случая, обьект std::string, тогда не нужно будет заморачиваться с копированием и уничтожением
Сборка персонального компьютера от Artline: умный выбор для современных пользователей