C ++:在派生类中重用operator +() [英] C++: Reuse operator+() in derived class

查看:46
本文介绍了C ++:在派生类中重用operator +()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种方法可以重用基类的 operator +(...)方法,类似于赋值运算符 operator =(...)在下面的示例中使用了吗?

Is there a way to reuse the operator+(...) method of the base class in a similar manner that the assignment operator operator=(...) is used in the example below?

重要提示:我不想使用抽象类/虚拟方法,我只是想知道下面的示例,以便我完全理解基本"用法.使用继承而不会过多地涉及多态性!在下面的示例中,可以以这种方式成功使用operator =(),是否可以使用operator +()?

IMPORTANT: I don't want to use abstract classes/virtual methods, I'm only curious about the example below for me to fully understand the "basic" usage of inheritance without going too much into polymorphism! The operator=() can be used successfully in this way in the example below, is it possible with the operator+()?

基类:

class Vector
{
private:
  int _x;
  int _y;
protected:

  // constructors & destructors here

  Vector& operator=(const Vector& source){...}

  Vector operator+(const Vector& source) const{...}

};

派生类:

class Position : public Vector
{
private:
  double _rho;
  double _phi;
public:

  // constructors & destructor here

  Position& operator=(const Position& source)
  {
    Vector::operator=(source); // slices source to its base-class part
    _rho = source._rho;
    _phi = source._phi;
    return *this;
  }

  Position operator+(const Position& source) const
  {
    /* 
    * HELP NEEDED HERE:
    * Some way of calling Vector::operator+() to avoid
    * code repetition and ensure consistency with the 
    * operator+ definition in the base class
    */
  }
};

谢谢

推荐答案

我的最初评论虽然有些浮躁,但仍然成立.话虽如此,我将您的问题重新实现为某种可以编译的解决方案.

My initial comment, while a bit flippant, still holds true. With that said, I re-implemented your problem into something that will compile to demonstrate a solution.

首先,您的类(如图所示)不需要分配运算符重载.它还不需要复制构造函数,析构函数,move构造函数或move赋值运算符.这是因为您没有动态的内容,因此内置的浅表副本/任务就足够了.

First, your class (as shown) does not need an assignement operator overload. It also does not need a copy constructor, destructor, move constructor, or move assignment operator. This is because you aren't holding anything dynamic, therefore built-in shallow copies/assignments suffice.

话虽如此,我以一种更加惯用的方式重新实现了您的 operator +().如果您可以执行 Derived + Derived ,人们希望也可以执行 Derived + = Derived .

With that said, I re-implemented your operator+() in a slightly more idiomatic fashion. If you can do Derived + Derived, people expect to be able to do Derived += Derived as well.

由于它们彼此相关,因此可以根据 operator + =()来实现 operator +() .唯一的技巧是利用按值传递.

Because these are related to each other, it is possible to implement operator+() in terms of operator+=(). The only trick is taking advantage of pass-by-value.

代码如下:

#include <iostream>

class Base {
 public:
  Base() = default;
  Base(int x, int y) : m_x(x), m_y(y) {}

  // Assignment operator not required, Rule of 0

  Base& operator+=(const Base& rhs) {
    m_x += rhs.m_x;
    m_y += rhs.m_y;

    return *this;
  }

  friend Base operator+(Base lhs, const Base& rhs) {
    lhs += rhs;

    return lhs;
  }

 // Needed to print a Derived object
 protected:
  int getX() const { return m_x; }
  int getY() const { return m_y; }

 private:
  int m_x = 0;
  int m_y = 0;
};

class Derived : public Base {
 public:
  Derived() = default;
  Derived(double rho, double phi) : Base(), m_rho(rho), m_phi(phi) {}
  Derived(int x, int y, double rho, double phi)
      : Base(x, y), m_rho(rho), m_phi(phi) {}

  Derived& operator+=(const Derived& other) {
    Base::operator+=(other);
    m_rho += other.m_rho;
    m_phi += other.m_phi;

    return *this;
  }

  friend Derived operator+(Derived lhs, const Derived& rhs) {
    lhs += rhs;

    return lhs;
  }

  friend std::ostream& operator<<(std::ostream& sout, const Derived& rhs) {
    return sout << "x: " << rhs.getX() << "\ny: " << rhs.getY()
                << "\nrho: " << rhs.m_rho << "\nphi: " << rhs.m_phi;
  }

 private:
  double m_rho = 0.0;
  double m_phi = 0.0;
};

int main() {
  Derived d1;
  Derived d2(2, 2, 1.1, 1.1);

  Derived d3 = d1 + d2;
  Derived d4 = d2 + d3;
  std::cout << "\nd4:\n" << d4 << '\n';

  std::cout << "\nd3:\n" << d3 << '\n';

  std::cout << "\nd2:\n" << d2 << '\n';
}

输出:

d4:
x: 4
y: 4
rho: 2.2
phi: 2.2

d3:
x: 2
y: 2
rho: 1.1
phi: 1.1

d2:
x: 2
y: 2
rho: 1.1
phi: 1.1

您可以看到我在做同一件事".在我的 operator + =()中,我首先调用 Base 版本.然后,我要照顾 Derived 成员.之所以可行,是因为当 operator + =()返回引用时, operator +()会按值获取其 lhs 参数,这意味着它是一个副本.副本由 operator + =()更改并返回.利用值传递的优势,我可以使用 operator + =()而不更改任何原始操作数.因此, operator +()的行为仍然符合预期.

You can see that I do "the same thing." In my operator+=(), I call the Base version first. Then I take care of the Derived members. This works because while operator+=() returns a reference, operator+() takes its lhs parameter by value, meaning it's a copy. The copy is altered by operator+=() and returned. Taking advantage of pass-by-value allowed me to use operator+=() without altering either of the original operands. So operator+() still behaves as expected.

这篇关于C ++:在派生类中重用operator +()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆