Перегрузка + оператор

Я пытаюсь ознакомиться с операторами в 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; Я получаю ошибку компилятора:

нет совпадения для ‘operator =’ в ‘c = MVec :: operator + (const MVec&)
const (((const MVec&) ((const MVec *) (& б))))

Когда я комментирую это, я получаю ошибку, обнаруженную glibc после первого std :: cout. Предположительно, я делаю что-то не так с временной переменной, которую создаю в функции operator +. К сожалению, я не достаточно умна, чтобы понять что. Любое понимание этого было бы очень полезно.

3

Решение

Вам нужно взять const ссылка на MVec в вашем конструкторе копирования, чтобы иметь возможность использовать его с временными файлами:

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

Другие решения

Ошибка времени компиляции легко объясняется: ваш оператор присваивания ожидаетconst ссылка в качестве аргумента, но вы не можете связать неconst ссылка на временный, так как он возвращается из вашего operator+(), Вид наивного исправления — заставить оператора взять const& вместо. Однако на самом деле вам вообще не нужно определять оператор присваивания копии! Созданная компилятором конструкция копирования, назначение копирования и деструктор — все в порядке. Вы можете просто удалить их, и вам лучше.

Удаление деструктора, в частности, решит и другую проблему: вы delete[]памяти в вашем деструкторе вы не распределили! Вы никогда не должны делать это. То есть, если вы исправите свой деструктор, он будет пустым, то есть вы можете просто удалить его.

2

этот

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 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];
1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector