我在C++ Faq lite中没有看到答案:
如何定义基类,以便每个继承它的类都需要定义析构函数?
我试过运行这个程序
struct VDtor { virtual ~VDtor()=0; };
struct Test:VDtor { virtual ~Test(){} };
int main() { delete new Test; return 0; }
Run Code Online (Sandbox Code Playgroud)
http://codepad.org/wFcE71w3 有错误
In function `Test::~Test()':
t.cpp:(.gnu.linkonce.t._ZN4TestD0Ev+0x1e): undefined reference to `VDtor::~VDtor()'
In function `Test::~Test()':
t.cpp:(.gnu.linkonce.t._ZN4TestD1Ev+0x1e): undefined reference to `VDtor::~VDtor()'
Run Code Online (Sandbox Code Playgroud)
那么,有可能吗?
Joh*_*itb 17
在某种意义上它是"可能的"(如果你的目标是派生类保持抽象,否则).但是它不会给你想要的结果:因为如果程序员没有这样做,编译器会隐式地创建一个析构函数.
它为此没有可能迫使派生类的作者明确声明构造.
(编辑:像@chubsdad 注意到的那样,你的特定代码中的错误是因为你需要定义基类的显式声明的析构函数).
编辑:只是为了好玩,还有的是necessiate显式声明的构造情况.考虑以下
struct Viral {
struct Dose { };
protected:
~Viral() throw (Dose) { }
};
struct Base {
virtual ~Base() throw() { }
};
struct Derived : Base, Viral { };
Run Code Online (Sandbox Code Playgroud)
此代码将无法编译,因为隐式声明的~Derived将具有throw (Dose)比~Base具有更宽松的异常规范- 因此它违反了覆盖器不应具有更宽松的异常规范的要求.您需要适当地显式声明析构函数
struct Derived : Base, Viral { ~Derived() throw() { } };
Run Code Online (Sandbox Code Playgroud)
但这并不是您问题的真正解决方案,因为派生类需要"合作"成为从Viral非静态数据成员派生或将其作为非静态数据成员.这也很丑啊:)
编辑:以下似乎是一种符合标准的方式来做到这一点
struct Viral {
struct Dose { };
protected:
~Viral() throw (Dose) { }
};
struct Base : virtual Viral {
virtual ~Base() throw() { }
};
Run Code Online (Sandbox Code Playgroud)
Clang和GCC(从v4.6开始)拒绝任何Base具有隐式声明的析构函数的派生类,因为它具有不兼容的异常规范(任何派生类都应该~Viral直接调用,而不是通过调用间接调用~Base,标准说明).Comeau接受了这一点,但我强烈怀疑它在这方面不符合要求.
| 归档时间: |
|
| 查看次数: |
1976 次 |
| 最近记录: |