我发现几乎每个虚拟析构函数的代码片段都将它作为公共成员函数,如下所示:
class Base
{
public:
virtual ~Base()
{
cout << "~Base()" << endl;
}
};
class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}
};
虚拟析构函数必须是公共的还是存在非公共虚拟析构函数有意义的情况?
答案 0 :(得分:19)
虚拟析构函数必须是公共的还是存在非公共虚拟析构函数有意义的情况?
马匹课程。如果需要多态删除,则使用public
虚拟析构函数,否则您的析构函数根本不需要虚拟。
关注 Herb's advice :
指南#4: 基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。
简而言之,您将离开两种情况中的一种。要么:
- 您希望通过基指针允许多态删除,在这种情况下,析构函数必须是虚拟和公共的;或
- 你没有,在这种情况下,析构函数应该是非虚拟的并受到保护,后者可以防止不必要的使用。
醇>
答案 1 :(得分:6)
就像非虚拟析构函数一样, 不是public
,但大部分时间都不是public
。
如果您的类是规则的例外,并且由于任何原因需要控制其实例的生命周期,那么析构函数必须是非virtual
。这将影响客户如何(或不能)利用该类的实例,但这当然是重点。由于析构函数是virtual protected
,唯一的另一个选项是{{1}}。
相关:Is there a use for making a protected destructor virtual?
答案 2 :(得分:1)
如果您计划通过特殊方法创建/销毁对象(例如,create / destroy),则没有必要。但是如果你在堆栈或堆上创建对象,则必须有公共析构函数。
答案 3 :(得分:1)
这里的问题是关于虚拟析构函数,因此我假设为什么需要这样的实现的原因的排列应该包括继承情况。问题的答案取决于以下内容:
1)如果您不希望实例化类,可以使用私有构造函数/析构函数。虽然,实例化可以通过同一个类中的另一个方法来完成。因此,当您想在类中使用MyDestructor()等特定方法来调用析构函数时,析构函数仍然可以置于私有之下。 对于Ex:Singleton设计模式。此外,在这种情况下,它会阻止该类被继承
2)如果要继承所有类,则不能允许私有基类析构函数(抛出编译错误)。但是,受保护的基类析构函数允许继承
3)受保护的虚拟析构函数的继承类型(公共和受保护)允许多级继承的安全方式A-> B-> C,以便在调用C的析构函数时,清除内存更好。
4)单独的私有析构函数不能允许删除(我不确定auto_ptr,但我认为即使这应该遵循使用“私有”析构函数的相同想法)当使用new动态分配内存时
到处都是,我看到使用私有析构函数可能容易出错,尤其是当一个不了解这种实现的人即将使用这样的类时。
始终欢迎受保护和公共析构,并且使用取决于上面给出的需求。
希望这澄清。
答案 4 :(得分:0)
这取决于,在许多情况下 YES 它应该是公开的。如果析构函数在私有部分下写入,那么您必须通过指针实例化它。
但是有一些例外情况,在私人部分设置desctuctor是正常的,例如单身......
答案 5 :(得分:0)
此处涉及两个单独的规则。首先,如果您的设计要求通过指向基础的指针删除派生类型的对象,则基础中的析构函数必须为虚拟。其次,如果一个成员函数(以及我广义上包含析构函数)是受保护的或私有的,那么可以调用它的上下文比它公开时更受限制(当然,如果析构函数是私有的,你可以' t来自该类)。例如:
class C {
protected:
virtual ~C();
friend void destroy_me(C*);
};
void destroy_me(C *cp) {
delete cp; // OK: destructor is accessible
}
void destroy_someone_else(C *cp) {
delete cp; // Error: destructor is not accessible
}