类内部的纯虚析构函数定义会导致编译错误
Pure virtual destructor definition inside class gives compilation error
pure virtual destructor
in基类应该有定义。否则,编译器将在链接期间从派生类析构函数生成对基类析构函数的调用,并将导致链接错误。
class base
{
public:
base()
{
cout << "constructor in base classn";
}
virtual ~base()=0
{}
};
编译错误:
然后我尝试在基类之外定义函数,如下所示:错误:function-definition上的pure-specifier
class base
{
public:
base()
{
cout << "constructor in base classn";
}
virtual ~base()=0;
};
base::~base()
{
}
这将删除编译错误,并且它的行为与我的理解一致。
但是我的问题是如何在基类之外定义纯虚析构函数来消除编译错误?
你的第二个例子是正确的
许多其他的答案都假设使用默认实现的纯虚函数是非法的,然而这是不正确的。
对于纯虚析构函数,必须有一个定义(参见xmoex answer中的链接)。
§10.4/2函数声明不能同时提供纯说明符和一个定义
但是,正如您注意到的,可以在声明之外提供定义
我看了这一页:
http://www.gotw.ca/gotw/031.htm和根据我的理解,纯虚析构函数必须有一个定义(即使是空的),因为每个派生类都必须调用基类析构函数
这样写的语法无效:
virtual ~base()=0
{}
如果你想提供纯虚成员函数的实现,你应该在类之外实现。大多数情况下不应该这样做,因为无论如何都不应该调用纯虚函数。然而,可以定义纯虚函数的实现。
实际上,纯虚析构函数必须有实现。这是因为在对象析构时调用所有基类的析构函数,而不管给定类中的析构函数是否为纯虚函数。
因此,如果您创建了从base
派生的任何类的实例,那么在某个时刻,该对象所属的所有类的析构函数将被调用,包括base::~base()
析构函数。如果你没有定义它,链接器将找不到所需的符号,并会报错。
析构函数是唯一的方法,即使它是纯虚函数,也必须有一个实现才能使它所定义的类有用。因此,与@Kiril的回答相反,我想说纯虚函数可以有实现。
有点跑题:
struct base {
virtual void func() = 0;
};
void base::func() { /* default implementation */ }
class derived : public base{
void func() { base::func(); } // have to explicitly call default implementation.
};
纯虚方法可以有实现,但它们使基类抽象,并强制派生类覆盖这些方法。
假设在基类中有一个指针成员。你想在析构函数中删除它,但又想使类抽象——所以你实现了纯虚析构函数。
这是一个实现细节——析构函数的实现不应该从外部可见。
- std::is_base_of表示ctor编译错误
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- 如何修复sfml c++代码编译错误
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- vscode下的Arduino代码出现意外编译错误
- 第三方 API 中的编译错误 - Visual Studio
- std::cout输出int时出现编译错误
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 提升图广度优先搜索前置编译错误
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 我在C++中遇到了这个奇怪的编译错误
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 现代OpenGL和GLEW Libraray的编译错误
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- C ++程序编译错误,找不到/访问文件
- 使用直接大括号初始化时,C++ 编译错误"声明末尾的预期";"
- 为什么传递非静态成员函数会导致编译错误?