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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> delete object with non-virtual destructor = UB ? 
V
    Опции темы
borisbn
Дата 6.10.2012, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Здравствуйте. Столкнулся с тем, что gcc на такой код
Код
struct Base {
    virtual void destroy() = 0;
};
struct Deriv : public Base {
    virtual void destroy() {
        delete this;
    }
    ~Deriv() { cout << "Deriv::~Deriv" << endl; }
};

int main()
{
   Base * a = new Deriv();
   a->destroy();
}

даёт такой warning
Цитата
warning: deleting object of polymorphic class type 'Deriv' which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]

Если бы я написал delete a; - у меня бы не было вопросов, в чём я не прав - в Base нужно добавить вирт.деструктор... это понятно. Непонятно следующее - откуда в приведённом коде UB ?

Я тут немного поэкспериментировал - добавил в Base и в Deriv классик, который печатает что-то в своём конструкторе и деструкторе - отрабатывают все 4
Код
struct TracerBase
{
   TracerBase() { cout << "TracerBase::TracerBase()" << endl; }
   ~TracerBase() { cout << "TracerBase::~TracerBase()" << endl; }
};

struct Base {
    virtual void destroy() = 0;
    TracerBase m_tracer;
};

struct TracerDeriv
{
   TracerDeriv() { cout << "TracerDeriv::TracerDeriv()" << endl; }
   ~TracerDeriv() { cout << "TracerDeriv::~TracerDeriv()" << endl; }
};

struct Deriv : public Base
{
    virtual void destroy() {
        delete this;
    }
    ~Deriv() { cout << "Deriv::~Deriv" << endl; }
    TracerDeriv m_tracer;
};

int main()
{
   Base * a = new Deriv();
   a->destroy();
}

http://liveworkspace.org/code/f476a3f7cf08...929fee22c25af52
Вывод
Цитата
TracerBase::TracerBase()
TracerDeriv::TracerDeriv()
Deriv::~Deriv
TracerDeriv::~TracerDeriv()
TracerBase::~TracerBase()


Вопрос: если не вызывать в явную деструктор базового класса, то в чём же тут UB ?
Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 6.10.2012, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 49
Всего: 110



Цитата(borisbn @  6.10.2012,  11:57 Найти цитируемый пост)
warning: deleting object of polymorphic class type 'Deriv' which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]

эта проверка появилась вроде только в 4.7.2, если не ошибаюсь.
Цитата(borisbn @  6.10.2012,  11:57 Найти цитируемый пост)
откуда в приведённом коде UB ?

ну ,компилятор справедливо предполагает, что раз уж ты используешь new, то где-то должен быть delete ;)

Цитата(borisbn @  6.10.2012,  11:57 Найти цитируемый пост)
если не вызывать в явную деструктор базового класса, то в чём же тут UB ?

насколько мне известно, наследники виртуальных классов обязаны реализовывать свой виртуальный деструктор.
а что там по стандарту - я хз.

PM WWW   Вверх
borisbn
Дата 6.10.2012, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(boostcoder @  6.10.2012,  12:31 Найти цитируемый пост)
наследники виртуальных классов обязаны реализовывать свой виртуальный деструктор

хммм. добавил virtual в деструктор Deriv и warning пропал... чего-то я недопонимаю  smile
Если в базовом нет вирт.деструктора, то какая разница виртуальный он в наследнике или нет.  smile 

Это сообщение отредактировал(а) borisbn - 6.10.2012, 13:51


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 6.10.2012, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 49
Всего: 110



Цитата(borisbn @  6.10.2012,  13:50 Найти цитируемый пост)
Если в базовом нет вирт.деструктора, то какая разница виртуальный он в наследнике или нет

в базовом он быть не обязан. а в наследниках обязан.
не знаю как объяснить, почему. а своими словами объяснять долго...

PM WWW   Вверх
tzirechnoy
Дата 6.10.2012, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 2
Всего: 16



При наличии деструктора у потомка и неперегружэнного destroy(), этот destroy() вызовет не тот деструктор.
PM MAIL   Вверх
Леопольд
Дата 6.10.2012, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 10
Всего: 13



может поэтому?
Код

#include <iostream>

using std::cout;
using std::endl;

struct Base {
    virtual void destroy() = 0;
};

struct Deriv : public Base {
    virtual void destroy() {
        delete this;
    }
    ~Deriv() { cout << "Deriv::~Deriv" << endl; }
};

struct Final: public Deriv
{
    ~Final() { cout << "Final::~Final" << endl; }
};

int main()
{
   Base * a = new Final();
   a->destroy();
}

http://liveworkspace.org/code/b65e4d394e7c...284536b3441c5b5


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
borisbn
Дата 7.10.2012, 07:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Спасибо. Понятно.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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