C++:在派生 class 中重用 operator+()
C++: Reuse operator+() in derived class
有没有一种方法可以重用基础 class 的 operator+(...)
方法,其方式类似于下面示例中使用赋值运算符 operator=(...)
的方法?
重要提示:我不想使用抽象 classes/virtual 方法,我只是对下面的示例感到好奇,因为它可以让我完全理解继承的“基本”用法,而不会过多涉及多态性! operator=() 可以在下面的示例中以这种方式成功使用,是否可以使用 operator+()?
基础class:
class Vector
{
private:
int _x;
int _y;
protected:
// constructors & destructors here
Vector& operator=(const Vector& source){...}
Vector operator+(const Vector& source) const{...}
};
派生 class:
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
*/
}
};
谢谢
我最初的评论虽然有点轻率,但仍然适用。话虽如此,我将您的问题重新实现为可以编译以演示解决方案的东西。
首先,您的 class(如图所示)不需要赋值运算符重载。它也不需要复制构造函数、析构函数、移动构造函数或移动赋值运算符。这是因为您没有持有任何动态内容,因此内置浅 copies/assignments 就足够了。
话虽如此,我以一种稍微更惯用的方式重新实现了您的 operator+()
。如果你能做到 Derived + Derived
,人们希望也能做到 Derived += Derived
。
因为这些是相互关联的,所以可以用operator+=()
来实现operator+()
。唯一的技巧是利用按值传递。
代码如下:
#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+=()
returns 是一个引用,但 operator+()
按值获取其 lhs
参数,这意味着它是一个副本。该副本由 operator+=()
更改并返回。利用按值传递的优势,我可以使用 operator+=()
而无需更改任何一个原始操作数。所以 operator+()
仍然按预期运行。
有没有一种方法可以重用基础 class 的 operator+(...)
方法,其方式类似于下面示例中使用赋值运算符 operator=(...)
的方法?
重要提示:我不想使用抽象 classes/virtual 方法,我只是对下面的示例感到好奇,因为它可以让我完全理解继承的“基本”用法,而不会过多涉及多态性! operator=() 可以在下面的示例中以这种方式成功使用,是否可以使用 operator+()?
基础class:
class Vector
{
private:
int _x;
int _y;
protected:
// constructors & destructors here
Vector& operator=(const Vector& source){...}
Vector operator+(const Vector& source) const{...}
};
派生 class:
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
*/
}
};
谢谢
我最初的评论虽然有点轻率,但仍然适用。话虽如此,我将您的问题重新实现为可以编译以演示解决方案的东西。
首先,您的 class(如图所示)不需要赋值运算符重载。它也不需要复制构造函数、析构函数、移动构造函数或移动赋值运算符。这是因为您没有持有任何动态内容,因此内置浅 copies/assignments 就足够了。
话虽如此,我以一种稍微更惯用的方式重新实现了您的 operator+()
。如果你能做到 Derived + Derived
,人们希望也能做到 Derived += Derived
。
因为这些是相互关联的,所以可以用operator+=()
来实现operator+()
。唯一的技巧是利用按值传递。
代码如下:
#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+=()
returns 是一个引用,但 operator+()
按值获取其 lhs
参数,这意味着它是一个副本。该副本由 operator+=()
更改并返回。利用按值传递的优势,我可以使用 operator+=()
而无需更改任何一个原始操作数。所以 operator+()
仍然按预期运行。