【问题标题】:C++: how to reuse code in covariant return types?C++:如何在协变返回类型中重用代码?
【发布时间】:2012-10-11 23:26:22
【问题描述】:

我有以下简单的类

class base
{
public:
  int x;
  base &set(int y)
    {
      x = y;
      return *this;
    }
};

并想创建一个具有附加功能的新功能,例如打印值 x。所以我这样做:

class derived : public base
{
public:
  void print()
    {
      cout << x << endl;
    }
};

现在在主程序中我想做类似的事情

D.set(2).print();

但是编译器会抱怨基类没有名为“print”的成员。

如果我尝试使用协变返回类型并将两个类写为

class base
{
public:
  int x;
  virtual base &set(int y)
    {
      x = y;
      return *this;
    }
};

class derived : public base
{
public:
  derived &set(int y)
    {
      x = y;
      return *this;
    }
  void print()
    {
      cout << x << endl;
    }
};

然后该语句工作得很好,但是我不得不在两个类中为“set”重写完全相同的函数体,即使唯一改变的是返回类型。

如果以后我需要更改 base::set 的功能,那么我将不得不通过所有派生类来更改“set”功能...有什么办法可以避免这种情况吗?提前致谢!

【问题讨论】:

  • 您实际上是创建base 对象还是打算成为一个“抽象”类?
  • 您是否有理由不想将print 放在基础上并根据需要覆盖?
  • 为什么不用前两个类的例子,在基类中做一个虚方法?
  • 请分享有关该类变量的定义或分配()的代码。 “D”是什么意思?
  • @delnan - 是的,我打算创建基类的对象。

标签: c++ inheritance covariance code-reuse


【解决方案1】:

根据您的情况,您或许可以使用CRTP

template <class D>
class base {
    D& set(int x) {
        …;
        return *static_cast<D*>(this);
    }
};

class derived : base<derived> { … };

【讨论】:

    【解决方案2】:

    C++ 像你说的那样工作,你说在你的基类set 返回base&amp;,所以这就是 C++ 所做的。但是为了解决这个问题,你有很多方法。

    首先,您不必在派生类中创建函数virtual 来覆盖它(请注意,虚拟调用比正常调用稍慢)。

    其次,您可以将基类实现称为base::set,因此代码如下:

    class base {
        ...
        base& set( int x ) {...}
    };
    class derived : public base {
        derived& set( int x ) {
            return static_cast<derived&>( base::set(x) );
        }
    };
    

    【讨论】:

    • 是的,这很好用,谢谢。只是我想避免演员表,我在另一个论坛上读到,其中很多意味着重新设计...
    猜你喜欢
    • 1970-01-01
    • 2011-09-02
    • 2017-02-28
    • 2021-03-21
    • 2011-02-10
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 2021-02-24
    相关资源
    最近更新 更多