考虑开发人员明确声明的没有destructor
和constructor
的类的情况。我理解,在这种情况下,类的destructor
将为implicitly declared
。那么destructor
是implicitly defined
是真的,只有当一个类的对象即将被销毁时才会这样吗?
构造函数的行为是否也与上面相同。只有在创建类的对象时才是implicitly defined
吗?
修改
class A {
public:
};
int main() {
}
在上面的代码中,将隐式声明~A()。我的问题是,只有当类的对象被实例化为
时,析构函数的定义是否会被隐式地生成才是真的。class A {
public:
};
int main() {
A a;
}
或者是否隐式定义,即使没有进行对象实例化?
答案 0 :(得分:5)
是的,隐式声明的默认构造函数和析构函数在用于创建或销毁对象的实例时是隐式定义的。用标准(C ++ 11)的话来说:
12.1 / 6:默认构造函数默认为默认构造函数,默认构造函数默认为已删除 (3.2)创建一个类类型的对象(1.8),或者在第一次声明后明确默认为它。
12.4 / 5:当使用odr-used(3.2)时,默认定义了一个默认的析构函数并且未定义为已删除的析构函数 销毁其类类型的对象(3.7)或在第一次声明后显式默认为它。
所以它们是在你的第二个代码片段中定义的,它创建并销毁类型为A
的对象,但不在第一个代码片段中,而不在第一个代码片段中。
答案 1 :(得分:0)
一方面,通常无法决定是否在任何非平凡的程序中创建/销毁对象*,另一方面,只要可观察的行为保持不变,它就无关紧要
但是,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() {}
答案 2 :(得分:0)
函数是否定义不是在运行时确定的,因此析构函数不能“定义,只有当对象[..] 约被销毁时 em>“只是因为你的可执行文件是静态的而不是为特定的运行而创建的。
但是,如果最终可执行文件中不存在对析构函数的调用,则链接器 可能选择 将完全删除该函数。< / p>
最后一点,请考虑以下示例:
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()
它不能做的事。