Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Освобождение памяти

397
13 декабря 2008 года
SergPas
527 / / 03.02.2007
Дан следующий "псевдокод":
Код:
class Object
{
public:
    Object& method();
    ...
}

Object& Object::method()
{
    Object* Obj=new Object(...);
    //Модифицируем объект *Obj и возвращаем его же
    return *Obj;
}

void main()
{
    Object X(...), Y(...);
    Y=X.method();
}
После такого присвоения необходимость в динамически выделенном объекте Obj экземпляра X класса Object отпала, и, следовательно, происходит утечка памяти... Вопрос: где освобождать память?
562
13 декабря 2008 года
tarekon
175 / / 19.08.2003
 
Код:
Object& temp = X.method();
Y = temp;
delete &temp;


Но я бы от такого кода избавлялся. Ибо если есть конструктор копирования, то можно написать
 
Код:
Object Object::method()
{
    Object Obj(...);
    //Модифицируем объект Obj и возвращаем его же
    return Obj;
}

и это будет гораздо правильнее, ибо метод перестает требовать от своего пользователя знание этой "особенности".
288
14 декабря 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: SergPas
После такого присвоения необходимость в динамически выделенном объекте Obj экземпляра X класса Object отпала, и, следовательно, происходит утечка памяти... Вопрос: где освобождать память?



На мой взгляд, код немного сложнее, чем он мог бы быть. А в чем состоит конечная цель? Может легче возвращать из функции указатель, а не ссылку? Опять же непонятно, что вернет функция, если вдруг вызов new закончится неудачей?

397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
На мой взгляд, код немного сложнее, чем он мог бы быть.

Может быть и сложней, чем есть на самом деле... Это целиком и полностью зависит от преследуемой цели...

Цитата:
А в чем состоит конечная цель?

Конечная цель состоит в том, чтобы приватные данные, изменяемые в методе method(), объекта X остались без изменений, но все изменения сохранились в объекте Y:

 
Код:
Y=X.method();
Поэтому и приходится создавать новый объект и уже его редактировать...
Выше упомянутый класс "работает" стабильно, правильно, без ошибок, если рассматривать с точки зрения его прямого назначения... за исключением утечки памяти, что само собой - не есть хорошо... И поэтому на такие "дырки" нужно сразу ставить "заплатки", а не оставлять на потом...
341
15 декабря 2008 года
Der Meister
874 / / 21.12.2007
[QUOTE=SergPas]Конечная цель состоит в том, чтобы приватные данные, изменяемые в методе method(), объекта X остались без изменений, но все изменения сохранились в объекте Y[/QUOTE]А почему не X.method(Y)?
397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
А почему не X.method(Y)?


Об этом я тоже думал... И такой вариант также будет реализован в классе... И работать он будет без проблем... Задача состоит в том, чтобы реализовать максимально удобный и надёжный класс...

12K
15 декабря 2008 года
__AleXX__
133 / / 02.04.2007
Ну, надежности ты этим методом не добавишь.
397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
Ну, надежности ты этим методом не добавишь.


Это почему же?

12K
15 декабря 2008 года
__AleXX__
133 / / 02.04.2007
Стопудово все начнется из-за утечек памяти.
Надежнее возвращать объект (правда произойдет лишнее копирование).
Классически возвращается ссылка на константный объект, но тут нечестными приемами можно его изменить, кроме того этот объект нужно будет где-то хранить.
Я бы оставил только один метод, который принимает ссылку на объект, который будет меняться.
12K
15 декабря 2008 года
__AleXX__
133 / / 02.04.2007
К стати, а почему, все же возвращается ссылка, а не указатель?
Типа, если возвращается ссылка то можно юзать методы объекта через '.'(1 знак), а если указатель - через '->'(2 знака) ?
341
15 декабря 2008 года
Der Meister
874 / / 21.12.2007
[QUOTE=SergPas]Задача состоит в том, чтобы реализовать максимально удобный и надёжный класс...[/QUOTE]Вы этот класс на рынке продавать будете, что ли? :) Нормально со сцылкой в качестве параметра.
Если Object имеет только параметризованные конструкторы, делайте фабрику и сплавляйте ей создание/удаление объектов (можете и с подсчётом ссылок). Но я не уверен, что вам это нужно.
P. S. Кстати, лучше бы, наверное, даже Y.method(X). Зависит, конечно, от задачи, но есть соглашения: обычно используют void method(const Object &), а не void method(Object &) const. Хоть это и не принципиально. Главное, чтобы у вас путаницы не возникало.
397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
Стопудово все начнется из-за утечек памяти.

Вот как раз этого я и хочу избежать...

Цитата:
Надежнее возвращать объект (правда произойдет лишнее копирование).

Целиком и полностью согласен... Но и тут начинаются проблемы со всеми вытекающими последствиями...

Цитата:
К стати, а почему, все же возвращается ссылка, а не указатель?

Потому что это (Object* Obj=new Object(...); )временный объект, занимаемая память под который должна быть освобождена...

Цитата:
Типа, если возвращается ссылка то можно юзать методы объекта через '.'(1 знак), а если указатель - через '->'(2 знака) ?

Я это как вариант даже не рассматривал... К тому же, если возвращается указатель, то объект, к которому присваивается этот указатель должен быть таким же указателем - иначе не прокатит... В этом случае нужно воспользоваться перегрузкой оператора ->... Но делать я этого не собираюсь: пускай семантика объектов и указателей на объекты остаётся прежней...

12K
15 декабря 2008 года
__AleXX__
133 / / 02.04.2007
Цитата: SergPas

Потому что это (Object* Obj=new Object(...); )временный объект, занимаемая память под который должна быть освобождена...


Что подразумеваешь под временным объектом указатель или тот, который создастся в куче?

Потому что если указатель - то он просто скопируется при возврате из функции.

397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
Что подразумеваешь под временным объектом указатель или тот, который создастся в куче?

 
Код:
Object* Obj
Вообщем весь динамически созданный объект...
Цитата:
Потому что если указатель - то он просто скопируется при возврате из функции.

... память на который он указывает будет очищена, что приведёт к ошибкам...

12K
15 декабря 2008 года
__AleXX__
133 / / 02.04.2007
На счет второго - не согласен, указатель - переменная где хранится адрес (в данном случае на память, выделенную под объект в куче),
переменная просто скопируется при возврате из функции.
И все будет Ок.

Это применительно к языку С++.
397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
в данном случае на память, выделенную под объект в куче


Я с Вами полностью согласен!!! Мы отходим от главной цели... Задача состоит в том, чтобы эту память очистить, после того, как скопируем её в другой объект...

12K
15 декабря 2008 года
__AleXX__
133 / / 02.04.2007
ну тогда используй шаблонный класс из стандартной библиотеки: auto_ptr, который принимать будет указатель и освобождать когда сам будет умирать, вот и все.
397
15 декабря 2008 года
SergPas
527 / / 03.02.2007
Цитата:
ну тогда используй класс из стандартной библиотеки auto_ptr, который принимать будет указатель и освобождать когда сам будет умирать, вот и все.


Вот за дельный совет спасибо!!! Попробуем...

240
16 декабря 2008 года
aks
2.5K / / 14.07.2006
Цитата: __AleXX__

Надежнее возвращать объект (правда произойдет лишнее копирование).


Если компилятор умеет NRVO - то не произойдет.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог