隐式定义类的析构函数
Destructor of a class implicitly defined
考虑开发人员没有显式声明destructor
和constructor
的类的情况。我理解在这种情况下,一个班级的destructor
将是implicitly declared
。那么,只有当类的对象即将被销毁时,destructor
才是implicitly defined
,这是真的吗?
是构造函数的行为也与上面相同。它是implicitly defined
仅当类的对象被创建?
编辑
class A {
public:
};
int main() {
}
在上面的代码中,~A()将隐式声明。我的问题是,只有当类的对象像
那样实例化时,析构函数的定义才会隐式地进行,这是否正确?class A {
public:
};
int main() {
A a;
}
或者它是隐式定义的,即使对象实例化没有完成
是的,隐式声明的默认构造函数和析构函数是在用于创建或销毁对象实例时隐式定义的。用标准c++ 11的话说:
12.1/6:默认构造函数是默认的,但没有定义为deleted,当它被odr使用时,它被隐式定义(3.2)创建其类类型(1.8)的对象,或者在第一次声明后显式默认该对象。
12.4/5:默认的且未定义为deleted的析构函数在被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()
,这是它不能做的。
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- 如何正确定义C++类析构函数并将其链接到主文件?
- 仅在 MacOS 上析构函数的未定义符号
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- 对已定义的接口析构函数的未定义引用
- 对 clang 中析构函数的未定义引用
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- 为什么这个自定义分配器的析构函数在 GCC/MSVS 的 stdlib 中被调用两次
- 使用自定义工具集获取动态退出析构函数链接错误 - eh 矢量析构函数
- 为什么在定义析构函数时隐式删除移动构造函数
- DIRECTX9 中自定义顶点的虚拟析构函数
- 编译器定义的移动构造函数与析构函数
- 我可以解决unique_ptr在<MyType>仅存储 nullptr 时不需要 MyType 析构函数定义吗?
- 为什么复制构造函数不是微不足道的,因为有一个用户定义的析构函数?
- 仅在删除包含对象的向量时调用自定义»析构函数«
- 这个递归类需要一个自定义析构函数?
- 如果基类析构函数是虚拟的,是否需要派生类析构函数定义
- 添加析构函数定义将创建运行异常
- 类内部的纯虚析构函数定义会导致编译错误
- c++虚析构函数定义