Неопределенное поведение с не виртуальными деструкторами - это проблема реального мира? - PullRequest
4 голосов
/ 24 декабря 2010

Рассмотрим следующий код:

class A 
{
public:
  A() {}
  ~A() {}
};

class B: public A
{
  B() {}
  ~B() {}
};

A* b = new B;
delete b; // undefined behaviour

Насколько я понимаю, стандарт C ++ гласит, что удаление b - неопределенное поведение, т. Е. может произойти все, что .Но в реальном мире мой опыт показывает, что ~ A () вызывается всегда и память освобождается правильно.

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

Очевидно, это не такЭто будет то, что вы хотите в нетривиальных случаях, но это, по крайней мере, последовательно.Вам известна любая реализация C ++, где вышеописанное НЕ происходит для показанного кода?

Ответы [ 4 ]

6 голосов
/ 24 декабря 2010

Это бесконечный вопрос в теге C ++: «Что такое предсказуемое неопределенное поведение». Легко решить все самостоятельно: получите каждую реализацию компилятора C ++ и проверьте, работает ли предсказуемое непредсказуемое. Это то, что вы должны сделать самостоятельно.

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

3 голосов
/ 24 декабря 2010

Насколько я знаю, нет реализации, где это не так. С другой стороны, наличие класса, в котором, если вы добавите в него не POD, он взорвется, это плохая вещь, которую вряд ли неразумно назвать ошибкой.

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

1 голос
/ 24 декабря 2010

Класс B почти всегда будет больше, чем A в нетривиальных случаях, потому что в нем есть экземпляр A, а также дополнительные члены B. Это ухудшается, когда вы вводите виртуальные члены.

Так что, хотя ~ A и будет вызван, легко увидеть, что подобные вещи могут привести к утечке памяти. Это неопределенное поведение не потому, что оно может не вызывать ~ A, что в принципе гарантировано, а из-за того, как управляется память.

1 голос
/ 24 декабря 2010

«Для показанного кода» очень маловероятно, что вы когда-нибудь найдете реализацию, которая будет работать. Это если исключить из рассмотрения различные «отладочные» реализации, которые специально и намеренно предназначены для отлова таких ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...