Pure virtual destructor in C++
写错了吗:
1 2 3 4
| class A {
public:
virtual ~A() = 0;
}; |
对于抽象基类?
至少在MSVC中编译…它会在运行时崩溃吗?
对。您还需要实现析构函数:
1 2 3 4 5 6
| class A {
public:
virtual ~A() = 0;
};
inline A::~A() { } |
应该足够了。
既然这次投票失败了,我应该澄清一下:如果你从A中得到任何东西,然后试图删除或销毁它,那么最终会调用A的析构函数。因为它是纯的,没有实现,所以会发生未定义的行为。在一个流行的平台上,它将调用pureCall处理程序并崩溃。
编辑:将声明修改为更符合要求,并使用http://www.comeacucomputing.com/tryitoutouting编译/
- 所以应该声明为virtual~a(),不带"=0"。如果您提供一个实现,它不是纯虚拟的
- 嗯,是的。纯只意味着派生类也需要提供一个实现。
- 实现纯虚拟功能实际上是合法的。对于提供默认实现非常有用,但强制子类显式调用它。
- msn和note如果你在头中有这个定义,你需要把"inline"放在它之前,以避免违反odr(一个定义规则)
- 为什么必须显式定义::~a(),因为我认为每个对象都有一个默认的析构函数?与任何类型的继承一样,始终调用析构函数链,不必总是定义基类析构函数。
- 如果要调用基类析构函数,则必须始终定义它。如果从未删除或显式销毁的子类,则这无关紧要。如果你这样做了,就是这样。
- 更好的方法是,一旦您声明了一个析构函数,它就不会自动为您实现。
- 我不明白你为什么漏掉了原始问题中的public:。你的答案本身似乎是说,使析构函数(隐式地)私有化使调用变得不可能,但它需要(隐式地)被调用;那么,为什么要使它私有化呢?
- @Marcvanleeuwen,更新了,虽然它并没有真正影响答案。我可能五年前为了减少必要的打字量而忽略了它。
- @Marcvanleeuwen,这是因为最初这个问题是在没有public:的情况下写的,因此我最初对析构函数不可访问的评论。
- 如果您没有为A::~A()提供定义,那么应该会得到一个编译时错误—一个链接错误。
- @MSN,你所说的这种未定义的行为和崩溃是什么意思?pastebin.com/uz2ny4z0此程序不会在Windows上崩溃。那是流行的平台吗?输出为:pastebin.com/pjndktpy
- @bobbogo"如果您不提供::~a()的定义,那么您应该得到一个编译时间"--对于编译器来说是看不到的。只有链接器会检测到它。
- 根据本CPP核心指南,我是否也需要=default其他特殊成员方法?
- 只是一个节点:即使通过使派生类变为纯的方式"强制"它声明析构函数,也可以使用没有任何(用户定义的)析构函数的派生类。godbolt.org/z/x7tcko公司
私有析构函数:当您创建派生类的对象时,它们会给您一个错误——否则不会。但可能会出现诊断。
12.4 Destructors
6 A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined.
具有纯虚拟析构函数的类是抽象类。注:
10.4 Abstract classes
2 A pure virtual function need be defined only if called with, or as if with (12.4), the qualified-id syntax (5.1).
[Note:a function declaration cannot provide both a pure-specifier and a definition —end
note ]
直接从草稿中提取:
1 2 3
| struct C {
virtual void f() = 0 { }; // ill-formed
}; |
- + 1。我认为Herb Sutter也有一些很好的信息:gotw.ca/gotw/031.htm。有趣的是,任何纯虚拟函数都可能提供了一个实现,而不仅仅是析构函数。
- 是的,这是你在面试中做的一件事,让面试官感到奇怪;)
- 事实上,在我的经验中,这并不少见。
- @尼尔·巴特沃斯:哪一个?
- @dirk-"任意函数"场景。发现它用于实现一些常见行为并不少见。
- @尼尔:啊,我明白了。我经常使用它。非常方便。
- 该语法需要哪个版本的C++?我在G++C++ 11上进行了测试,没有编译
- 等等,如果编译器接受,那么使用EDOCX1[4]是否安全?