C++ 虚函数本质上应该有一个定义吗?
是否有必要对虚函数进行定义 考虑以下示例程序:C++ 虚函数本质上应该有一个定义吗?,c++,virtual-functions,undefined-reference,C++,Virtual Functions,Undefined Reference,是否有必要对虚函数进行定义 考虑以下示例程序: #include <iostream> using namespace std; class base { public: void virtual virtualfunc(); }; class derived : public base { public: void virtualfunc() { cout << "vf in derived class\n";
#include <iostream>
using namespace std;
class base
{
public:
void virtual virtualfunc();
};
class derived : public base
{
public:
void virtualfunc()
{
cout << "vf in derived class\n";
}
};
int main()
{
derived d;
return 0;
}
#包括
使用名称空间std;
阶级基础
{
公众:
void virtualfunc();
};
派生类:公共基
{
公众:
void virtualfunc()
{
您需要提供一个定义,或者将其标记为抽象/纯虚拟
void virtual virtualfunc() = 0;
除非将函数定义为“纯虚拟”,否则需要提供虚拟函数的实现(及其默认行为)
所以你的例子可以是:
class base
{
public:
void virtual virtualfunc() {} //intentionally do nothing;
};
或
是的,您需要一个主体,但您所指的可能是一个纯虚函数,它不需要基类中的定义
定义它们的语法如下所示:
void virtual virtualfunc() = 0;
ISO C++标准规定,必须定义一个类不是纯虚的所有虚方法。
参考:
C++03标准:10.3虚拟函数[class.Virtual]
类中声明的虚函数应定义,或在该类中声明为纯函数(10.4),或两者都定义;但不需要诊断(3.2)
因此,要么让函数成为纯虚拟函数,要么为其提供定义
如果您使用的是gcc,如果您没有遵循此标准规范,可能会出现一些奇怪的错误。文档也记录了这些错误:
ISO-C++标准规定了一个类不是纯虚的所有虚拟方法必须被定义,但是不需要任何违反此规则的诊断。/8
。基于此假设,GCC将只在定义其第一个此类非内联方法的转换单元中发出隐式定义的构造函数、赋值运算符、析构函数和类的虚拟表
因此,如果无法定义此特定方法,链接器可能会抱怨缺少明显不相关符号的定义。不幸的是,为了改进此错误消息,可能需要更改链接器,但这并不总是可以做到
解决方案是确保定义所有非纯虚拟方法。请注意,即使析构函数声明为纯虚拟,也必须定义析构函数[class.dtor]/7
<> P>响应VTABLE的错误:在这种情况下,虚拟命令告诉C++在基类中生成方法的虚拟表。这样,当使用多态性时,C++可以用在运行时以相同名称从派生类中替换方法的基类虚拟方法。无法进行此替换。若要修复此错误,您需要实现该方法或通过在定义末尾添加“=0”将其设置为纯虚拟
作为对编辑的响应:将对象实例化为基类时没有收到错误的原因是基类不需要访问虚拟表。另一方面,如果您实际尝试使用此方法,则应该会收到错误,因为不存在任何实现。换句话说,即使您可以实例化基类的对象它不是一个完整的类。简洁且几乎说明了一切。重新编辑:如果你不实例化
派生的或基类,链接器为什么要对这两个类中的任何方法做任何事情?如果没有引用这些类,链接器甚至没有理由尝试查找它们在对象文件中。(除非您正在构建库。)这就是深层次的原因!!
void virtual virtualfunc() = 0;