2013-10-15 4 views
0

У меня есть класс, который имеет член private, который объявлен в куче в конструкторе. Затем, в деструкторе, это delete ред. Теперь я хотел бы добавить метод для изменения этой переменной. Я хотел бы иметь возможность использовать ссылку, но я не уверен в специфике используемой памяти, и я хотел бы знать, что я делаю это правильно (проект может быть довольно большим в отделе памяти).Параметры: Где они объявлены?

class A 
{ 
private: std::string str; 
/* ... */ 
public: 
A() 
{ 
str = new std::string(""); 
} 
~A(){delete str;} 

// method to modify str. 
}; 

Если я пройду по ссылке, какие шаги следует предпринять для устранения утечек памяти и минимизации использования памяти? При этом я не хочу, чтобы все это было оптимистично с оптимизацией.

Как я должен писать свои получатели и сеттеры для члена, находящегося в куче? Копировать конструкторы, что-то еще?

+1

Обратите внимание, что класс std :: string уже выполняет собственное управление памятью, которое включает инкапсуляцию конструктора копирования, перемещения конструктора и оператора присваивания. Вам не нужно, когда агрегировать класс, который уже имеет это, сделать это снова. –

+1

Следовательно, если в вашем случае класс, который агрегирован (частный член), имеет собственное управление памятью (как это делает std :: string), скорее не выделяйте его в кучу.Если вы обеспокоены тем, что у вас есть много зависимостей в вашем файле заголовка, что может быть причиной использования кучи, вместо этого используйте псевдоним pimpl_. –

+0

Не используйте указатели и распределение кучи, пока вы в ней не нуждаетесь. – Raja

ответ

2

первым, private: std::string str; должен быть private: std::string* str;

текущая модель управления памятью является classic RIIA model.. Во-первых, есть несколько вопросов, которые нужно очистить.

  • Будет ли объект str принадлежащим только классу A?
  • Вы хотите использовать str вне времени жизни класса A?

Если вы ответите «нет» на вышесказанное, эта модель не очень подходит для вашей потребности.

В противном случае вы могли бы продолжить реализацию этих функций-членов, здесь я просто даю некоторые подсказки.

Геттеры может возвращать ссылку обратно,

std::string const& getStr() { 
    return *str; 
} 

сеттер может просто изменить значение,

void setStr(std::string const& s){ 
    *str = s; 
} 

Для конструктора копирования, вы можете просто вызвать конструктор копирования из std::string и сделать глубокую копию ,

A(A const& obj){ 
    str = new std::string(*obj.str); 
} 
+0

Я думаю, что wiki-страница RAII ужасна - гораздо лучшая ссылка будет http://www.informit.com/articles/article.aspx?p=30642&seqNum=8 – Raja

+0

хорошая ссылка, отредактирована. –

+0

Вместо того, чтобы объявлять 'str' в качестве указателя, было бы лучше сделать то, что ответил другой: не использовать' new' и 'delete'. –

4

Вы по-прежнему усложняете свой probl Эм. Код должен выглядеть так:

class A 
{ 
    private: std::string str; 

    public: 
     A() { str = ""; } 
     std::string GetStr() { return str; } 
     void SetStr(std::string value) { str = value; } 
}; 

Конструктор инициализирует ваш элемент данных пустой строкой. Вам не нужен деструктор. Класс string выполнит всю очистку для вас. И вы можете использовать свое поле данных, как в приведенных выше методах.

Не добавляйте специальные методы копирования/перемещения. Просто внимательно прочитайте руководство по использованию класса строк.

+1

Конструктор по умолчанию для 'std :: string' уже инициализирует его пустой строкой. –

+0

Это правда. Я старался быть ближе к исходному коду. –

+1

Getter и setter должны использовать const & for return и параметр соответственно. :-) –

Смежные вопросы