繁体   English   中英

明确删除析构函数而不调用delete

[英]Explicitly deleting destructors and not calling delete

我正在阅读C ++ 11常见问题并注意到这一点:

 class X4 { ~X4() = delete; // Disallow destruction } 

这隐含地也不允许移动X4。 允许复制,但已弃用。

我也找到了这个引用

删除析构函数的定义将需要在free-store上进行分配,因为静态和自动对象隐式调用析构函数:

 struct C { ~C()= delete; //prevent automatic and static objects }; 

但是,这种技术没有看起来那么有用,因为它也可以防止删除表达式。 但是Singleton对象可以使用它

这是有道理的。 我的问题是,它是否被认为是一个具有明确删除的析构函数的Singleton的好习惯? 此外,如果有人知道任何其他情况,你不应该打电话给delete ,请告诉我。

实际上,您有时可能会发现自己处于破坏特定类型对象的安全状态。 所以你要删除析构函数以防止任何人尝试。

在Singleton的情况下,只有一个类型的实例,未能销毁它可能比没有清理的实例的负载更少。

Singletons(或任何其他全局可用对象)的问题之一是您可能无法控制它们的依赖关系。 然后很难找到一个安全的销毁顺序 - 如果全局数据库对象记录到您已安全关闭连接的全局记录器对象,但可选地,全局记录器对象通过全局数据库对象记录到数据库,那你就有问题了。

虽然你可以通过不破坏全局数据库对象来“解决”这个问题,但我认为这不应该被称为“良好实践”。 这听起来更像是一种在没有重新设计的情况下处理坏情况的简单方法(尽管在我的例子中,重新设计也可能非常简单 - 只需确保DB记录器或DB本身对日志消息执行一些有用的操作连接关闭时。吞下它们,或将它们重定向到另一个可用目的地)。

可能有“好”的设计,其中特定类型的对象不能被破坏,但它不是C ++类设计的通常方式。

此外,如果有人知道任何其他情况,你不应该打电话给删除,请告诉我。

使用内存池是我能想到的一种情况。

有一种情况是永远不会调用析构函数,即使是自动变量:当用户编写显式析构函数X::~X时,类X的匿名联合的析构函数。 由于工会是匿名的,根本就没有办法,它的析构函数可以被称为X::~X (不现在如何调用析构函数,因为它不知道如何调用析构函数)。

顺便说一句,在这种情况下,用户无法声明要删除联合析构函数(同样缺少名称),但可以隐式删除它。

奇怪的是在这种情况下, 默认的析构函数X::~X会调用匿名联合的析构函数。 但是,只要允许,这只是一个纯粹的形式问题,而析构函数调用没有任何效果。 这是因为只有当联合的所有变体都具有琐碎的析构函数(因此联合本身也是如此)时才允许这样做; 如果它们中的任何一个具有非平凡的析构函数,则会隐式删除union的析构函数,使得X的默认析构函数无法运行(有效删除)。

但是,这并不意味着不能使用包含匿名联合的类X其中至少有一个成员具有非平凡的析构函数。 它只是意味着用户编写的X::~X必须直接破坏匿名联合的活动变体,绕过联合本身的已删除析构函数。 如果类包含允许知道哪个变体处于活动状态的其他成员,则这是可能的。 类似地, X构造函数应该直接构造并集的至多一个变体,绕过匿名并集的(可能已删除的)构造函数(除非变量是POD,否则这样的构造函数不应该直接赋值给union的变体)。 实际上,匿名联合的特殊成员函数是一种幻像实体,它们不是非常重要的,并且其唯一的作用是可能被删除,以有效地将该已删除的状态传播到包含X的相应特殊成员函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM