在C++中,如何在派生类中重载二进制运算符

In C++, how to overload a binary operator in a derived class?

本文关键字:运算符 重载 二进制 C++ 派生      更新时间:2023-10-16

我是一个C++新手,这是我在练习编码时遇到的问题。假设我有一个看起来像的基类

class base {
public:
    base();
    friend base operator+(const base& lhs, const base& rhs) {
        base result;
        //some calculation
        return result;
    }
};

和派生类

class derived : base {
public:
    derived();
    friend derived operator+(const derived& lhs, const derived& rhs) {
        // what to write here?
    }
}

有没有一种简单的方法可以在两个派生类对象之间重载+运算符?基本上,除了我想要之外,一切都会一样

derived result;

而不是

base result;

在第一行中,以便派生类的构造函数负责对象的一些额外初始化。这似乎是一个常见的多态性特征,我想一定有一种优雅的方法可以做到这一点,但我不确定如何。。。

非常感谢!

Niko

当您必须处理时,实现operator+()会遇到很多问题具有基类和派生类。

我能想到的最好的办法是实现virtual operator+=()成员函数,返回对正在调用的对象的引用上的功能

struct base
{
   // The usual other functions...
   virtual base& operator+=(base const& rhs) = 0;
};
// Provide an implementation in the base class that
// takes care of what can be taken care of in the base
// class.
// This is allowed even when the function is pure
// virtual.
base& base::operator+=(base const& rhs)
{
   // Do the needful.
   // Return a reference to this object.
   return *this;
}
struct derived : base
{
   virtual base& operator+=(base const& rhs)
   {
      // Add checks to make sure that rhs is of
      // derived type.
      // Call the base class implementation to take
      // care of updating base class data.
      base::operator+=(rhs);
      // Take care of updating the data of this object.
      // Return a reference to this object.
      return *this;
   }
};

然后你可以使用:

base* bPtr1 = new derived;
base* bPtr2 = new derived;
(*bPtr1) += (*bPtr2);

类层次结构中的二进制运算符实际上不起作用。试验和探索是可以的,但不能保证满足。

在这种情况下,制作工作代码的一种方法是将其制作成模板。

template <class P>
P operator+ (const P& p1, const P& p2);
class base {
  friend base operator+<> (const base& p1, const base& p2);
};
class derived : public base {
  friend derived operator+<> (const derived& p1, const derived& p2);
};
template <class P>
P operator+ (const P& p1, const P& p2)
{
  P p; 
  // do something
  return p;
}

最好将类和运算符+都放在命名空间中,这样它就不会与其他类似的运算符冲突。

如果我正确理解你的问题,derived中定义的friend operator+需要与base中定义的相同,只是后者的返回类型需要是derived。一种方法是为derived定义一个构造函数(可能是private),该构造函数接受base参数。

derived(base const& b)
: base(b)
// additional initialization for derived data members
{}

(或取base为值,std::move为值,构造base子对象)

然后,在derived

friend derived operator+(const derived& lhs, const derived& rhs) {
    return static_cast<base const&>(lhs) + static_cast<base const&>(rhs);
}

这将调用baseoperator+,然后使用上面定义的构造函数构造一个derived实例。