Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов деструктора после, оператора присваивания. Почему? 
V
    Опции темы
Rickert
Дата 20.4.2009, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 0
Всего: 52



Есть класс:
Код
class aPacket
{
  public:
    inline char* apGetData() const            {return data;}
    inline unsigned long apGetLength() const  {return length;}
    inline char apGetType() const             {return type;}

    aPacket(char* in);
      void apClearPacket();
      void apChewPacket(char* in = 0);
      virtual void apApartPacket() {};

    virtual ~aPacket() = 0;

  protected:
    char* data;
    unsigned long length;
};

От него наследую:
Код
class aPacketIni : public aPacket
{
  public:
    aPacketIni(char* in);
      void apApartPacket();
      void aPreparePacket();

      const aPacketIni operator=(const aPacketIni& p);

    ~aPacketIni();
};

Описание второго:
Код
const aPacketIni aPacketIni::operator=(const aPacketIni& p)
{
  apClearPacket();//функция чистит дин. созданную информацию

  length = p.apGetLength();
  data = new char[length];
  memcpy(data, p.apGetData(), length);
  type = p.apGetType();

  this->version = p.version;

  return (*this);
}

//=============================================================================

aPacketIni::~aPacketIni()
{
  apClearPacket();
}

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


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
azesmcar
Дата 20.4.2009, 11:01 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Rickert

Видимо потому что оператор присваивания возвращает обьект по значеню а не по ссылке smile
PM   Вверх
Rickert
Дата 20.4.2009, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 0
Всего: 52



Да, так и есть. Тогда я не понимаю почему у меня второй класс работает нормально. Пошёл искать ошибку. Спасибо!
solved smile 


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
pompei
Дата 20.4.2009, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: нет
Всего: 6



Как создаёте: в стеке или в куче?
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
math64
Дата 20.4.2009, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



А рекурсии почему не возникает? По return (*this); объект должен скопироваться в место, предоставленное вызвавшей функцией для помещения результата, а для этого должен быть вызван оператор копирования.
PM   Вверх
zim22
Дата 20.4.2009, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(math64 @  20.4.2009,  11:38 Найти цитируемый пост)
А рекурсии почему не возникает? По return (*this); объект должен скопироваться в место, предоставленное вызвавшей функцией для помещения результата, а для этого должен быть вызван оператор копирования.

вы случайно не путаете конструктор копирования с оператором присвоения?


--------------------
PM MAIL   Вверх
math64
Дата 20.4.2009, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Понятно. По return (*this); создаётся новый объект с помощью копирующего конструктора (а не оператора копирования), поскольку было выделено место для объекта, а объект ещё был не создан. Поскольку копирующий конструктор не определён, компилятор создаст его сам (причём неправильный - скопруется указатель data, а не будет выделятся новая память). Таким образом, у двух объектов будут одинаковые data. После выхода из оперетора копирования, поскольку результат операции никуда не присваивается и больше не нужен, вызывается деструктор и data удаляется. В скопированном объекте data указывает на удалённую память.
Вывод: 
  1. operator=() должен возвращать ссылку или ничего, его агрумент тоже должен быть ссылкой (но возможны исключения)
  2. Вместе с operator=() нужно создавать копирующий конструктор, чтобы они работали согласованно.
PM   Вверх
zim22
Дата 20.4.2009, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(math64 @  20.4.2009,  13:36 Найти цитируемый пост)
2. Вместе с operator=() нужно создавать копирующий конструктор, чтобы они работали согласованно.

и деструктор тоже нужно свой определить.



--------------------
PM MAIL   Вверх
azesmcar
Дата 20.4.2009, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



math64
1. Для класса автоматически буду сгенерированы (если они нужны и если они не написаны пользователем)
  • Дефолт конструктор
  • Копирующий конструктор
  • Деструктор
  • Оператор присваивания
2. Писать свои стоит лишь в том случае - если они будует отличатся от сгенерированных.
3. Если вам понадобилось явно написать копирующий конструктор или оператор присваивания - скорее всего нужно написать все 4.

Вот в принципе базовые правила для так называемой "Большой четверки" smile

PM   Вверх
zim22
Дата 20.4.2009, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(azesmcar @  20.4.2009,  14:45 Найти цитируемый пост)
Вот в принципе базовые правила для так называемой "Большой четверки"

а я знаю большую тройку. и дефолт конструктор в ней не обязателен.

Цитата

Существует весьма полезное эмпирическое правило: если класс нуждается в деструкторе, потребуются также оператор присвоения и конструктор копий. Это правило зачастую называют "правилом трёх" (Rule of Three), поскольку когда необходим деструктор, необходимы все три элемента управления копированием.


Это сообщение отредактировал(а) zim22 - 20.4.2009, 14:57


--------------------
PM MAIL   Вверх
azesmcar
Дата 20.4.2009, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата

а я знаю большую тройку. и дефолт конструктор в ней не обязателен.

А где я писал что обязателен?
PM   Вверх
zim22
Дата 20.4.2009, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(azesmcar @  20.4.2009,  14:56 Найти цитируемый пост)
А где я писал что обязателен?

здесь. не прямо, но косвенно smile
Цитата(azesmcar @  20.4.2009,  14:45 Найти цитируемый пост)
3. Если вам понадобилось явно написать копирующий конструктор или оператор присваивания - скорее всего нужно написать все 4.



--------------------
PM MAIL   Вверх
azesmcar
Дата 20.4.2009, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



zim22

Цитата

скорее всего нужно


Цитата

обязателен


разницы нет?
PM   Вверх
zim22
Дата 20.4.2009, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



azesmcar, любите же вы придираться к словам  smile 


--------------------
PM MAIL   Вверх
azesmcar
Дата 20.4.2009, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата

azesmcar, любите же вы придираться к словам  smile  

Я? smile
Конструктор скорее всего понадобится потому что если в классе есть что копировать или присваивать (причем не тривиально а нужен для этого свой оператор/копирующий конструктор) то скорее всего нужен конструктор чтобы его проинициализировать. Это может и не быть дефолт конструктор, но какой-то понадобится. Это типа рекомендации над чем надо задумываться когда пишешь и вовсе не означают что они обязательны.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0541 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.