在C++;,如何在派生类中重载二进制运算符? 我是C++新手,这是我在练习编码时遇到的问题。假设我有一个基类 class base { public: base(); friend base operator+(const base& lhs, const base& rhs) { base result; //some calculation return result; } };

在C++;,如何在派生类中重载二进制运算符? 我是C++新手,这是我在练习编码时遇到的问题。假设我有一个基类 class base { public: base(); friend base operator+(const base& lhs, const base& rhs) { base result; //some calculation return result; } };,c++,operator-keyword,derived-class,C++,Operator Keyword,Derived Class,和派生类 class derived : base { public: derived(); friend derived operator+(const derived& lhs, const derived& rhs) { // what to write here? } } 有没有一种简单的方法可以在两个派生类对象之间重载+运算符?基本上一切都是一样的,除了我想要的 derived result; 而不是 base result;

和派生类

class derived : base {
public:
    derived();
    friend derived operator+(const derived& lhs, const derived& rhs) {
        // what to write here?
    }
}
有没有一种简单的方法可以在两个派生类对象之间重载+运算符?基本上一切都是一样的,除了我想要的

derived result;
而不是

base result;
在第一行中,使派生类的构造函数负责对象的一些额外初始化。这似乎是一个常见的多态性特征,我想一定有一个优雅的方法来实现它,但我不确定如何

非常感谢


Niko

执行
操作符+()
在您必须处理的时候,会遇到很多问题 具有基类和派生类

我能想到的最好方法就是实现一个
虚拟
操作符+=()
成员 函数,该函数返回对正在调用的对象的引用 功能打开

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);

如果我正确理解您的问题,则
派生的
中定义的
友元运算符+
需要与
基本的
中定义的运算符相同,但后者的返回类型需要是
派生的
。一种方法是为
派生的
定义一个构造函数(可能是
私有的
),该构造函数接受一个
参数

derived(base const& b)
: base(b)
// additional initialization for derived data members
{}
(或按值取
base
,然后移动
std::move
以构造
base
子对象)

然后,在
派生的

friend derived operator+(const derived& lhs, const derived& rhs) {
    return static_cast<base const&>(lhs) + static_cast<base const&>(rhs);
}
友元派生运算符+(常量派生和lhs、常量派生和rhs){
返回静态施法(lhs)+静态施法(rhs);
}

这将调用
base
操作符+
,然后使用上面定义的构造函数构造一个
派生的
实例。

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

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

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;
}
模板
P运算符+(常数P&p1、常数P&p2);
阶级基础{
友元基运算符+(常数基和p1、常数基和p2);
};
派生类:公共基{
友元派生运算符+(常量派生和p1,常量派生和p2);
};
模板
P运算符+(常数P&p1、常数P&p2)
{
P;
//做点什么
返回p;
}

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

显然与您的问题无关,但是:为什么要返回对局部变量的引用?@zenith,因为它可以工作。@n.m.您能添加一个答案来更彻底地解释吗?您正在引入运行时检查这可能会失败。@n.m.,是的。这就是为什么我说“我能想到的最好的”。我希望有人有更好的解决方案。但这并不能解决所提出的问题,即避免基类和派生类之间的代码重复。@n.m.,可以在基类中提供一个实现来处理公共代码,让派生类实现调用它。使操作符虚拟与否的问题可能很重要,但它与发布的问题是正交的。您可以提取通用代码,而无需进行任何虚拟操作。