【问题标题】:MI function definition in one base class not sufficient for virtual function of another base class一个基类中的 MI 函数定义不足以满足另一个基类的虚函数
【发布时间】:2017-11-18 14:36:18
【问题描述】:

我有一个继承自接口和基类的派生类。该接口定义了一个虚函数GetId,在另一个基类中实现。

class ITestClient
{
  public:
    virtual int GetId() = 0;
};

class BaseClient
{
  public:
    int GetId();
}

int BaseClient::GetId()
{
  return 10;
}

class TestClient : public ITestClient, public BaseClient {
};

我收到unimplemented pure virtual method 'GetId'。所以我可以这样做来修复编译错误...

class TestClient : public ITestClient, public BaseClient {
  int GetId()
  {
    return BaseClient::GetId();
  }
};

为什么基类BaseClientGetId的具体函数定义不足以作为接口虚函数的实现?

【问题讨论】:

  • 为什么不让BaseClient 派生自ITestClient
  • 你问为什么语言是这样定义的?还是你认为编译器有bug?
  • 想象一下编译器按照您期望的方式工作。如果您从另一个类Unrelated 派生会发生什么,该类也恰好有一个名为GetId() 的方法(与ITestClient 没有任何关系;假设它来自第三方库)?更糟糕的是,假设 Unrelated 最初没有 GetId() 方法,并且您的程序运行良好;但后来第三方作者出于自己的原因添加了私人GetId()。 C++ 对fragile base classes 有足够的问题。
  • 或者考虑这个:class Base { virtual int GetId() { return 42; } }; class Unrelated {}; class Derived : public Base, public Unrelated {}; 到目前为止很好:Derived d; d.GetId(); 将返回 42。现在,有人将 private: int GetId() { return -1; } 添加到 Unrelated。在你的理想世界里应该发生什么?应该是错误吗? Unrelated::GetId() 应该被忽略吗?还是应该 d.GetId() 默默地改变含义并开始返回 -1 在它返回 42 之前的位置?
  • @IgorTandetnik 这很有意义,谢谢。我对继承有错误的假设

标签: c++ c++11 multiple-inheritance virtual-functions vtable


【解决方案1】:

不确定我是否理解这个问题。 BaseClient is-not-A ITestClientis-A 关系是所需的继承属性)。所以BaseClient中的定义不能是那个接口函数的实现。

你朋友的儿子不会因为你把他带到你的车里就开始看起来像你,但是你自己的儿子会。这就是等价关系。

【讨论】:

  • 我明白了。我想,既然 BaseClient 和 ITestClient 都“在同一辆车里”,编译器可以让它们彼此相处。
  • 在 Java 中,等效代码完全按照提问者的想法工作。所以答案需要特定于 C++。
  • 当然,因为代码是 C++ 并且他的标签是 C++/C++11,但我认为没有理由认为这个问题与 C++ 无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
相关资源
最近更新 更多