如何在不修改 C++ 中的 LHS 参数的情况下实现 `+` 运算符?
How to implement `+` operator without modifying the LHS argument in C++?
我正在尝试了解重载运算符在 C++ 中的工作原理。我设法弄清楚如何实现 +=
和 =
运算符,但我正在努力使用 +
运算符。编译器告诉我运算符只能接受一个或两个参数。我似乎不知道如何正确 return 结果。
我可以作为参数的对象是运算符的 LHS 和 RHS,但在我看来,我必须创建 class 的第三个实例以某种方式存储和 return 结果。我认为 +
操作员不应该自己修改 LHS 或 RHS。
此外,在方法中创建新实例将不起作用,因为该对象将在方法完成后被删除。
那么如何正确地将结果存储在新实例中?
这是我到目前为止尝试过的:
#include <iostream>
class smallclass
{
public:
smallclass();
smallclass(int x);
smallclass& operator+=(smallclass&y);
smallclass& operator=(smallclass& y);
smallclass& operator+(smallclass& y);
int a;
};
smallclass::smallclass()
{
}
smallclass::smallclass(int x)
{
this->a = x;
}
smallclass& smallclass::operator+=(smallclass&y)
{
this->a += y.a;
return *this;
}
smallclass& smallclass::operator=(smallclass& y)
{
int value = y.a;
this->a = value;
return *this;
}
smallclass& smallclass::operator+(smallclass& y)
{
int value = y.a;
this->a += value;
return *this;
}
int main()
{
smallclass a = smallclass(5);
smallclass b = smallclass(6);
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
// a = 5
// b = 6
a += b;
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
// a = 11
// b = 6
a = b;
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
// a = 6
// b = 6
smallclass c;
c = a + b;
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
std::cout << c.a << std::endl;
// a = 12 should be 6
// b = 6
// c = 12
return 0;
}
您正在 returning *this
来自 operator+
。您应该 return 一个包含新结果的对象。通过 returning *this
你是说 x + y
的结果总是 x
,这是不正确的。结果是一个新值,不同于 x
和 y
。请注意 return 类型不应是引用,因为 returned 值不引用任何现有实例。
smallclass smallclass::operator+(smallclass& y)
{
smallclass result;
result.a = this->a + y.a;
return result;
}
您还应该阅读 const
正确性。通过使 y
成为 const
引用,您向用户保证您的操作员不会修改 y
。使整个成员函数const
也是如此。它向您的 class 的用户保证操作员不会修改 this
。没有这些 const
,您将无法在 const
个实例中使用您的运算符。
smallclass smallclass::operator+(const smallclass& y) const
{
smallclass result;
result.a = this->a + y.a;
return result;
}
一种更惯用的方法是根据 operator+=
和复制构造函数来实现 operator+
。这样,您就不必重复自己。
smallclass smallclass::operator+(const smallclass& y) const
{
smallclass result(*this);
result += y;
return result;
}
您可以为许多操作员执行此操作。值得注意的是,比较运算符都可以仅根据两个基本比较来实现,例如 operator==
和 operator<
.
实现operator+
的规范版本是这样的:
friend smallclass operator+ (smallclass op1, smallclass const& op2) {
op1 += op2;
return op1;
}
这种方法在可能的情况下利用了复制省略,还利用了 operator+=
的现有实现。
如果您想禁止左侧的自动转换,您可以使用以下版本进行交换加法:
smallclass operator+ (smallclass rhs) const {
rhs += *this;
return rhs;
}
如果加法不可交换,你会使用
smallclass operator+ (smallclass const& rhs) const {
return smallclass(*this) += rhs;
}
(最后一版不能完全省略一份)
我正在尝试了解重载运算符在 C++ 中的工作原理。我设法弄清楚如何实现 +=
和 =
运算符,但我正在努力使用 +
运算符。编译器告诉我运算符只能接受一个或两个参数。我似乎不知道如何正确 return 结果。
我可以作为参数的对象是运算符的 LHS 和 RHS,但在我看来,我必须创建 class 的第三个实例以某种方式存储和 return 结果。我认为 +
操作员不应该自己修改 LHS 或 RHS。
此外,在方法中创建新实例将不起作用,因为该对象将在方法完成后被删除。
那么如何正确地将结果存储在新实例中?
这是我到目前为止尝试过的:
#include <iostream>
class smallclass
{
public:
smallclass();
smallclass(int x);
smallclass& operator+=(smallclass&y);
smallclass& operator=(smallclass& y);
smallclass& operator+(smallclass& y);
int a;
};
smallclass::smallclass()
{
}
smallclass::smallclass(int x)
{
this->a = x;
}
smallclass& smallclass::operator+=(smallclass&y)
{
this->a += y.a;
return *this;
}
smallclass& smallclass::operator=(smallclass& y)
{
int value = y.a;
this->a = value;
return *this;
}
smallclass& smallclass::operator+(smallclass& y)
{
int value = y.a;
this->a += value;
return *this;
}
int main()
{
smallclass a = smallclass(5);
smallclass b = smallclass(6);
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
// a = 5
// b = 6
a += b;
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
// a = 11
// b = 6
a = b;
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
// a = 6
// b = 6
smallclass c;
c = a + b;
std::cout << a.a << std::endl;
std::cout << b.a << std::endl;
std::cout << c.a << std::endl;
// a = 12 should be 6
// b = 6
// c = 12
return 0;
}
您正在 returning *this
来自 operator+
。您应该 return 一个包含新结果的对象。通过 returning *this
你是说 x + y
的结果总是 x
,这是不正确的。结果是一个新值,不同于 x
和 y
。请注意 return 类型不应是引用,因为 returned 值不引用任何现有实例。
smallclass smallclass::operator+(smallclass& y)
{
smallclass result;
result.a = this->a + y.a;
return result;
}
您还应该阅读 const
正确性。通过使 y
成为 const
引用,您向用户保证您的操作员不会修改 y
。使整个成员函数const
也是如此。它向您的 class 的用户保证操作员不会修改 this
。没有这些 const
,您将无法在 const
个实例中使用您的运算符。
smallclass smallclass::operator+(const smallclass& y) const
{
smallclass result;
result.a = this->a + y.a;
return result;
}
一种更惯用的方法是根据 operator+=
和复制构造函数来实现 operator+
。这样,您就不必重复自己。
smallclass smallclass::operator+(const smallclass& y) const
{
smallclass result(*this);
result += y;
return result;
}
您可以为许多操作员执行此操作。值得注意的是,比较运算符都可以仅根据两个基本比较来实现,例如 operator==
和 operator<
.
实现operator+
的规范版本是这样的:
friend smallclass operator+ (smallclass op1, smallclass const& op2) {
op1 += op2;
return op1;
}
这种方法在可能的情况下利用了复制省略,还利用了 operator+=
的现有实现。
如果您想禁止左侧的自动转换,您可以使用以下版本进行交换加法:
smallclass operator+ (smallclass rhs) const {
rhs += *this;
return rhs;
}
如果加法不可交换,你会使用
smallclass operator+ (smallclass const& rhs) const {
return smallclass(*this) += rhs;
}
(最后一版不能完全省略一份)