重载 + 运算符
Overloading + operator
我正在尝试熟悉C++运算符。我想我会用一个简单的向量加法案例来做到这一点。不幸的是,我似乎遇到了一些问题。我的类定义如下:
#ifndef _MVEC_H_
#define _MVEC_H_
#include "Error.h" //I define things like throw(message) here, it works and is not the issue
class MVec {
private:
double vec[3];
public:
MVec();
MVec(double &);
MVec(double *);
MVec(MVec &);
MVec & operator=(MVec &);
inline double & operator[](const int i);
inline const double & operator[](const int i) const;
MVec operator+(const MVec &) const;
~MVec();
};
MVec::MVec() {}
MVec::MVec(double &a) {
for(int i = 0; i < 3; i++)
vec[i] = a;
}
MVec::MVec(double *a) {
for(int i = 0; i < 3; i++)
vec[i] = *a++;
}
MVec::MVec(MVec &rhs) {
for(int i = 0; i < 3; i++)
vec[i] = rhs[i];
}
MVec & MVec::operator=(MVec &rhs) {
if(this != &rhs)
for(int i = 0; i < 3; i++)
vec[i] = rhs[i];
return *this;
}
inline double & MVec::operator[](const int i) {
#ifdef _CHECKBOUNDS_
if(i < 0 || i >= 3)
throw("Subscript out of bounds");
#endif
return vec[i];
}
inline const double & MVec::operator[](const int i) const {
#ifdef _CHECKBOUNDS_
if(i < 0 || i >= 3)
throw("Subscript out of bounds");
#endif
return vec[i];
}
MVec MVec::operator+(const MVec &vec1) const {
MVec ans;
for(int i = 0; i < 3; i++)
ans[i] = vec[i] + vec1[i];
return ans;
}
MVec::~MVec() {
delete[] vec;
}
#endif
[] 运算符似乎按预期工作。不幸的是,向量加法运算符没有。具体来说,当我运行代码时:
#include "Error.h"
#include "MVec.h"
#include <cstdlib>
#include <iostream>
int main(int argc, char *argv[]) {
MVec a, b, c;
a[0] = 1; a[1] = 2; a[2] = 3;
b[0] = 5.9906; b[1] = 72.1139; b[2] = 83.1324;
//c = a + b;
std::cout << (a + b)[0] << std::endl;
std::cout << (a + b)[1] << std::endl;
std::cout << (a + b)[2] << std::endl;
exit(0);
}
当我取消注释行 c = a + b;我收到编译器错误:
与 'c = MVec::operator+(const MVec&) 中的 'operator=' 不匹配 const(((const MVec&)((const MVec*)(& b))))'
当我注释掉它时,我在第一个 std::cout 之后收到一个检测到 glibc 的错误。据推测,我对在运算符+函数中创建的临时变量做错了什么。不幸的是,我不够聪明,无法弄清楚是什么。对此的任何和所有见解都将非常有帮助。
复制构造函数中获取对MVec
的const
引用,以便能够将其与临时函数一起使用:
MVec(const MVec &);
这同样适用于赋值运算符,构造函数采用double
:
MVec(const double &); // or no reference, MVec(double);
MVec& operator=(const MVec& rhs);
还应从析构函数中删除delete [] vec
,因为vec
不是动态分配的。这是 glibc 错误的可能原因。
现在,为了表达诸如
SomeVec = 1.0 + SomeOtherVec;
您需要将operator+
声明为非会员:
MVec operator+(const MVec& lhs, const MVec& lhs);
这将允许在 LHS 和 RHS 上进行隐式转换。通常,将这些类型的运算符作为非成员函数是一个好主意,以保证 LHS 和 RHS 操作数之间的对称性。
另一方面,根本不允许从double
进行隐式转换可能更有意义。您可以通过使相关的构造函数explicit
来实现这一点:
explicit MVec(double);
时错误很容易解释:赋值运算符期望非const
引用作为参数,但不能将非const
引用绑定到临时引用,因为它是从operator+()
返回的。这种幼稚的解决方法是让操作员取const&
。但是,您实际上根本不需要定义复制赋值运算符!编译器生成的复制构造、复制赋值和析构函数都很好。你可以删除它们,你会过得更好。
特别是删除析构函数还可以解决您的另一个问题:您正在析构函数中delete[]
尚未分配的内存!你永远不应该这样做。也就是说,如果您修复了析构函数,它将是空的,即,您也可以将其删除。
这个
MVec MVec::operator+(const MVec &vec1) const {
MVec ans;
for(int i = 0; i < 3; i++)
ans[i] = vec[i] + vec1[i];
return ans;
}
应定义为具有 this MVec operator+(const MVec &vec1, const MVec &vec2) const
定义的非成员函数。 然后,您需要修改以添加 vec1[i] + vec2[i],假设您的目标是将两个向量中的每个值相加。
此外,您应该添加边界检查。如果任何一个向量的长度小于三个,你就会崩溃。您应该将较短向量的长度相加,或者不将它们相加,因为长度并不相同。例
int loopVar = 0;
if (vec1.length() > vec2.length())
loopVar = vec2.length();
else
loopVar = vec1.length();
for (int i = 0; i < loopVar; i++)
ans[i] = vec1[i] + vec2[i];
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- C++20概念:需要运算符重载
- 使用赋值运算符重载从类中返回jobject
- 在运算符重载定义中使用成员函数(const错误)
- 字节到位运算符重载C++
- 为什么在运算符重载时需要参考?
- 类中 c++ 的运算符 + 重载
- 算术复合运算符重载为非成员
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 交换运算符 + 重载会导致无限递归
- 如何理解新的运算符重载?
- 向量保持复数的运算符重载
- 如何创建运算符重载?
- 链接列表运算符重载没有打印出我想要的内容
- C++:需要帮助了解运算符重载错误
- 使用模板化运算符重载 XOR 运算符失败
- 如何确保接受的C++模板类型使运算符重载?
- 运算符重载使用运算符+添加类模板