Деструктор класса, неявно определенного

Рассмотрим случай класса, который не имеет destructor а также constructor явно заявлено разработчиком. Я понимаю что destructor для класса будет implicitly declared в этом случае. Тогда правда ли, что destructor является implicitly defined, только когда объект класса собирается быть уничтоженным?

Поведение конструктора также такое же, как указано выше. Это implicitly defined только когда объект класса создан?

РЕДАКТИРОВАТЬ

class A {
  public:

};
int main() {

}

В приведенном выше коде ~A() будет объявлено неявно. Мой вопрос заключается в том, правда ли, что определение деструктора будет сделано неявно, только если объект класса создан как

class A {
      public:

    };
    int main() {
      A a;
    }

Или это неявно определяется, даже если создание объекта не сделано?

3 ответа

Решение

Да, неявно объявленные конструкторы и деструкторы по умолчанию неявно определяются, когда они используются для создания или уничтожения экземпляров объекта. В словах стандарта (C++ 11):

12.1 / 6: Конструктор по умолчанию, который по умолчанию и не определен как удаленный, неявно определяется, когда он используется odr (3.2) для создания объекта своего типа (1.8) или когда он явно дефолтен после его первого объявления.

12.4 / 5: деструктор, который по умолчанию и не определен как удаленный, неявно определяется, когда он используется odr (3.2) для уничтожения объекта своего типа класса (3.7) или когда он явно дефолтен после его первого объявления.

Таким образом, они определены в вашем втором фрагменте кода, который создает и уничтожает объект типа A, но не в первом, чего нет.

С одной стороны, зачастую невозможно решить, был ли когда-либо создан / уничтожен объект в любой нетривиальной программе *, с другой стороны, это не имеет большого значения, пока наблюдаемое поведение остается тем же.

Тем не менее, есть тонкая грань между defined when object created/destroyed, а также defined if needed, В моем примере ниже, Foo::Foo() должно быть определено, потому что есть потенциал для этого. Однако вы спрашиваете, определен ли он при создании объекта, и последний не является разрешимым.


*:

class Foo {};
int main(int argc, char *argv[]) {
    if (argc>1) Foo(); // <- impossible to decide if ever constructed/destroyed
}

// On the other hand, compiler might be smart enough to observe that
// Foo does not have any visible behaviour, remove Foo entirely, and in
// effect spit out this:
int main() {}

То, определена ли функция, не является чем-то, что определяется во время выполнения, поэтому деструктор не может быть " определен, только когда объект [..] собирается быть уничтоженным " просто потому, что ваш исполняемый файл статичен и не создан для определенного запуска.

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


Для последнего пункта рассмотрим этот пример:

class A {
  A() {}
  ~A() {}
};
class B {
  A a; // cannot access dtor nor ctor of A
};

Если вы никогда не создаете экземпляр B это будет на самом деле скомпилировать и связать, потому что нет B::B() и нет B::~B() когда-либо синтезируется. Однако, если вы попытаетесь создать объект B компилятор назовет вас красочными именами просто потому, что вы заставили его синтезировать B::B() а также B::~B() что он не может сделать.

Другие вопросы по тегам