【问题标题】:Inheriting from both an interface and an implementation C++从接口和实现 C++ 继承
【发布时间】:2016-10-23 07:59:06
【问题描述】:

我通常会在发布任何内容之前尝试在这里找到答案,但我什至不确定如何提出我的问题。

这就是我想要做的...我想定义一个基本接口和一个派生接口。然后,我想用额外的变量和方法来实现基本接口。最后,我想从实现的基本接口实现一个派生类,但也从派生接口实现。我不了解你,但我的头很痛。

如果我执行以下操作,我会在 DerivedFloat 代码下得到不明确的定义,因为该代码“看到”来自 IBase(通过 IDerivedFloat 继承)的 GetBaseValue 方法以及从 Base 继承的 GetBaseValue。

当然,必须有一种方法来派生一个使用基本实现的扩展特性的类,并确保它实现所需的 IDerivedFloat 方法。

现在...这是一个虚拟示例,用于展示我在概念上试图实现的目标。这不是现实生活中的例子。

template <typename VALUE_TYPE>
class IBase
{
public:
  virtual VALUE_TYPE GetBaseValue() const = 0;
};

class IDerivedFloat : public IBase<FLOAT>
{
public:
  virtual void SetBaseValue(const FLOAT & value) = 0;
};

// Implementation of Base
template <typename VALUE_TYPE>
class Base : public IBase<VALUE_TYPE>
{
public:
  VALUE_TYPE GetBaseValue() const { return m_BaseValue; }

protected:
  VALUE_TYPE m_BaseValue;
}

// Uses expanded Base AND implements IDerivedFloat
class DerivedFloat : public Base<FLOAT>, public IDerivedFloat
{
public:
   void SetBaseValue(const FLOAT & value) { m_BaseValue = value };
}

【问题讨论】:

  • 我通常会在发布任何内容之前尝试在这里找到答案 -- 所以你在任何搜索中都没有找到“钻石继承”或virtual inheritance?跨度>
  • 不是 C++ 专家。我第一次听说钻石继承这个词。至于“虚拟继承”,我有。但很明显,从您的评论来看,我不知道如何利用这些信息来解决我的问题。
  • 您是否点击了我评论中的链接?它基本上是您接受的答案的副本。

标签: c++ inheritance interface


【解决方案1】:

您可以使用virtual inheritance 解决此问题:

class IDerivedFloat : virtual IBase<FLOAT>
{
public:
  virtual void SetBaseValue(const FLOAT & value) = 0;
};

template <typename VALUE_TYPE>
class Base : virtual IBase<VALUE_TYPE>
{
public:
  VALUE_TYPE GetBaseValue() const { return m_BaseValue; }

protected:
  VALUE_TYPE m_BaseValue;
}

使用虚拟继承为派生类提供一个基类成员的实例,而不是每次它存在于类层次结构中时一个实例。

【讨论】:

  • 谢谢安迪!看起来它做了我想做的事......而且你的回答比“呃,你没有研究过虚拟继承”提供更多信息:)
【解决方案2】:

多重继承是一个问题,正是因为您遇到了歧义问题,但有一些方法可以解决它。你必须明确地告诉编译器你从哪个 super 调用不明确的函数,方法是在函数调用前加上 super 的名称和一个双冒号。

示例:
- C 继承自 A 和 B。
- A 和 B 都有 add() 函数。
- 在 C 中,你必须说 A::add() 或 B::add() 来告诉编译器使用哪一个。

详细信息和更完整实现的链接:http://www.cprogramming.com/tutorial/multiple_inheritance.html

【讨论】:

  • 谢谢。我确实尝试过!但是让我烦恼的是派生类将同时包含这两个定义......我试图避免这种情况。这使我得出结论,我可能没有以正确的方式解决问题,也许吧??
  • 如果你试图停止同时拥有这两个函数,我唯一的想法可能是用孩子本身的另一个函数覆盖它们,但这并没有摆脱父函数,只是覆盖它们。他们仍然可以访问。我不确定你只能继承一个类的一部分,你必须要么全部继承,要么什么都不继承。
  • 上面的安迪提供了答案。再次感谢您的帮助 Kadima。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 2012-04-10
  • 2016-02-12
相关资源
最近更新 更多