Деструктор класса, неявно определенного - PullRequest
2 голосов
/ 19 декабря 2011

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

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

EDIT

class A {
  public:

};
int main() {

}

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

class A {
      public:

    };
    int main() {
      A a;
    }

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

Ответы [ 3 ]

5 голосов
/ 19 декабря 2011

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

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

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

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

0 голосов
/ 19 декабря 2011

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

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


В качестве последнего пункта рассмотрим следующий пример:

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(), чего он не может сделать.

0 голосов
/ 19 декабря 2011

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

Однако между 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() {}
...