деструкторы: тривиальность против неявного определения - PullRequest
4 голосов
/ 14 января 2009

Как я понимаю стандарт, тривиальный деструктор - это тот, который объявлен неявно и в классе которого есть только базовые и нестатические члены с тривиальными деструкторами. Учитывая рекурсивность этого определения, мне кажется, что единственное условие «остановки рекурсии» - это найти базовый или нестатический член с неявно объявленным деструктором (т.е. объявленным пользователем). Если это правильно, это должно означать, что тривиальный деструктор - это тот, который «не должен ничего делать», и, следовательно, он будет объявлен (неявно), но не определен. Говоря по-другому: правильно ли говорить, что неявно определенный деструктор (то есть «он что-то делает») не может быть тривиальным согласно стандартному определению?

Извините за глупый вопрос, но я бы хотел немного прояснить ситуацию ...

Ответы [ 3 ]

6 голосов
/ 14 января 2009

Нет. Неявно определенный, тривиальный деструктор по определению тривиален :) Разница между объявлением и определением вещи в том, что для того, чтобы компилятор даже увидел , что деструктор доступен, всегда должно быть объявление. Так что, если вы не предоставите один, он неявно предоставит один.

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

struct a {
private:
    ~a();
};

struct bug {
    // note: can't be destructed
    a a_;
};

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

Теперь я думаю, что тривиальность деструкторов / конструкторов в основном используется для наложения ограничений на вашу программу. Например, объекты, имеющие нетривиальные версии, нельзя объединять в союзы. С другой стороны, вы можете удалить объект, имеющий неполный тип, при условии, что у него есть тривиальный деструктор. Обратите внимание, что если ваша программа не может решить, был ли фактически определен тривиальный деструктор, компилятору разрешено опустить его определение. Это так называемое правило as-if. Компилятор должен вести себя так, как будто он соответствует стандарту - оптимизации не имеют значения, если они не меняют смысла программы.

3 голосов
/ 14 января 2009

Ваша формулировка немного неудачна. Например. Конечно, рекурсия также заканчивается, когда у вас заканчиваются члены и базовые классы. Эти проблемы с формулировками, похоже, еще больше сбивают вас с толку.

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

Тривиальные деструкторы существуют, потому что программисты на C помещают структуры в объединения. Этот код должен быть легальным в C ++, поэтому понятие тривиального деструктора было изобретено для C ++. Все структуры C имеют тривиальные деструкторы при компиляции в C ++.

0 голосов
/ 14 января 2009

Рассмотрим эти два класса:

class A {
};

class B {
private:
     A obj;
};

Деструкторы обоих этих классов неявно определены. Тем не менее, в то же время, они оба тривиальны по стандартному определению.

...