0

我有以下简单的课程

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”功能......有什么办法可以避免这种情况吗?提前致谢!

4

2 回答 2

2

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

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

class derived : base<derived> { … };
于 2012-10-11T23:58:37.257 回答
1

C++ 像你说的那样工作,你在基类中说setreturn base&,所以这就是 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) );
    }
};
于 2012-10-11T23:43:49.520 回答