在C ++中从纯虚拟变为虚拟

时间:2013-04-20 13:19:44

标签: c++ virtual

我有一个有5个子类的基类。

如果在我的基类中我有这个:

virtual CpuPort &getsecondDataPort()=0;

那么这意味着必须为所有子类实现该方法,对吗?

但是我不希望这样,因为我知道只有当我有一个特定子类的对象时我才会调用该方法,所以我认为我可以写这个:

virtual CpuPort &getsecondDataPort();

并仅在我想要的子类中实现它。但这给了我这个错误:

/base.cc:254: undefined reference to `vtable for BaseCPU'

和其他子类:

undefined reference to `typeinfo for BaseCPU'

其中BaseCPU是我的基类对象。

因为它是更大的库(实际上是模拟器)的一部分,所以我希望尽可能减少更改。所以请不要在你的子类中定义类似的东西'因为我想遵循目前为止组织代码的方式,除非这是解决问题的唯一方法。

关于为什么会发生这种情况的任何想法?

由于

3 个答案:

答案 0 :(得分:3)

  

这意味着必须为所有子类实现该方法,对吗?

仅当您要创建这些子类的直接实例时。如果子类没有实现纯虚函数,它将是抽象的 - 这是本身

  

但是这给了我这个错误:

这是因为虚函数已声明,但未定义。如果函数不是纯虚函数,则必须提供定义。

在这种情况下,你不能提供一个什么都不做的虚拟实现,因为你的函数应该返回一个引用,并且在没有返回任何内容的情况下从值返回函数的末尾流出未定义的行为符合C ++ 11标准的第6.6.3 / 2段。

如果你的基类有一个类型CpuPort的数据成员叫(比如说)myCpuPort,另一方面,你可以这样做:

virtual CpuPort &getsecondDataPort() { return myCpuPort; }

答案 1 :(得分:1)

似乎唯一的解决方案是在基类中提供一个空实现(考虑到你的限制)。

考虑以下情况:

 struct Base
 {
    virtual void foo() = 0;
 };
 struct Derived1
 {
 };
 struct Derived2
 {
    virtual void foo() {};
 };

 Base* p1 = new Derived1;
 Base* p2 = new Derived2;
 p1->foo();
 p2->foo();

假设编译器让这个代码通过(它没有,这很好)。第二次通话会发生什么?

答案 2 :(得分:1)

您已声明成员函数但未定义它。您需要提供getsecondDataPort的实现。

CpuPort& BaseCPU::getsecondDataPort()
{
     return somevar_;
}