我有一个课声明如下:

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.

如果您想知道为什么默认情况下不是所有虚拟的原因,则原因是调用虚拟函数比调用非虚拟函数要慢一些。哦,带有虚函数的类的对象每个都占用更多字节。

09-10 05:19