【问题标题】:Abstract base class virtual pure method that takes itself as a parameter以自身为参数的抽象基类虚纯方法
【发布时间】:2018-03-21 12:25:41
【问题描述】:

抱歉措辞不佳,我不太清楚如何表达这个问题。

我有一个基类 A,它有一个纯虚运算符+=,它接受一个自身的实例。在派生类 B 中,我想覆盖基类的 operator+= 以便它采用 B 的实例(而不是 A)。

// Abstract base class
template <class T>
class A
{
    A() = default;

    virtual A<T>& operator+=(const A&) = 0;
}

// Derived class
template <class T>
class B : public A<T>
{
   T some_field = 3.14159;

   B(const T x) : A(), some_field(x) {}

   B<T>& operator+=(const B& b) override
   {
       this.some_field += b.some_field;

       return (*this);
   }
}

我明白为什么这不起作用;这两种方法是不同的函数,因为它们需要不同的参数。但是,我假设必须有某种方法来保证任何从 A 派生的类都将实现 operator+=,其中它将派生类的实例作为参数。

virtual operator+=(const <this_class_type>&) = 0;

请问您能提供一个解决方案吗?非常感谢!

【问题讨论】:

  • 我敢说你考虑得不够仔细。思考 Liskov 替代原则。您不打算支持将通用 A 添加到 B,但这正是 A 指定的合同,您试图绕过。
  • 是的,我意识到上面的代码实际上是这样做的,我希望它能帮助澄清我的意图:)

标签: c++ inheritance c++17 virtual-functions abstract-base-class


【解决方案1】:

实现此目的的一种方法是使用T 作为参数:

template<typename T>
class IBase
{
public:
    virtual IBase& operator+=(const T& Instance) = 0;
};

class CDerived : IBase<CDerived>
{
public:
    IBase& operator+=(const CDerived&) override
    {
        return *this;
    }
};

class COtherDerived : IBase<COtherDerived>
{
public:
    IBase& operator+=(const COtherDerived&) override
    {
        return *this;
    }    
};

int main(int argc, char** argv)
{
    CDerived Derived1, Derived2;
    Derived1 += Derived2;
    COtherDerived Derived3;
    // Derived3 += Derived1; <-- Will not compile
}

【讨论】:

  • 噢!不知道为什么我没有想到这一点。感谢您的解释,现在对我来说更有意义了。我仍然要求 T 是原始类型,所以我在基类中添加了另一个模板参数来保存派生类类型。再次感谢!
  • 是的,您的初始代码示例没有显示您正在使用的 T 所以,我不确定您是否需要一种或两种模板类型,但我们可以看到您解决了它: )
  • 当所有派生类都有不同的基类时,拥有基类有什么意义?在此示例中,您可以完全删除基类,您将获得完全相同的结果。
  • @super - 基类强加了派生类应该实现的契约。我想这就是作者想要达到的目的。使用基础,您可以提供与IBase 一起使用的模板代码。
  • @user7119460 你的例子一般都很好:) 如果不是,我将无法回答:D
猜你喜欢
  • 2014-04-20
  • 1970-01-01
  • 2019-08-31
  • 2012-09-18
  • 2012-10-01
  • 2019-04-20
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
相关资源
最近更新 更多