我有一个课声明如下:
class TestFoo {
public:
TestFoo();
virtual void virtualFunction();
void nonVirtualFunction();
};
我尝试以这种方式实现
TestFoo::TestFoo(){}
void TestFoo::nonVirtualFunction(){}
在编译时返回错误:
undefined reference to vtable for TestFoo
我试过了 :
TestFoo::TestFoo(){}
void TestFoo::nonVirtualFunction(){}
void TestFoo::virtualFunction(){}
可以编译,与这些帖子的答案一致:
Undefined reference to vtable
undefined reference to vtable
令我感到困惑的是,我认为声明虚函数的全部目的是不需要定义它。在此示例中,我不打算创建任何TestFoo实例,而是创建从TestFoo继承的(具体)类的实例。但是,我仍然想为TestFoo的每个子类定义函数nonVirtualFunction。
我有没有做对的事?
谢谢 !
最佳答案
您的描述与抽象类的情况完全匹配。将您的虚拟函数声明为:
virtual void VirtualFunction () = 0;
这意味着您没有在此类中实现该功能。结果,该类变得抽象。即,不能实例化此类的裸对象。
另外,您应该提供一个虚拟析构函数。
更新:一些澄清...
该语言允许您重新定义非虚拟函数。但是,在某些情况下可能会调用错误的版本:
derived D; // rB is a reference to base class but it
base & rB=D; // points to an object of the derived class
rB.NonVirtualFunction (); // The base-class version is called
因此,现在强烈建议不要重新定义非虚拟功能。请参阅Scott Meyers的“有效的C++,第三版:改进程序和设计的55种特定方法”,项目36:“切勿重新定义继承的非虚函数”。
另请参见项目7:“在多态基类中声明虚拟的析构函数”。一个例子:
base * pB = new derived;
delete pB; // If base's destructor is not virtual,
// ~derived() will not be called.
如果您想知道为什么默认情况下不是所有虚拟的原因,则原因是调用虚拟函数比调用非虚拟函数要慢一些。哦,带有虚函数的类的对象每个都占用更多字节。