Member 13508014 Ответов: 3

перегрузка оператора "+" в C++


#include <iostream>

using namespace std;

class Test {
private:
	int mx;
	float my;
	int medata; //some extra data

public:
	Test() { mx = my = medata = 0; }
	Test(int x, float y, int edata) { mx = x; my = y; medata = edata; }

	void print() { cout << "x = " << mx << " y = " << my << " edata = " << medata << endl; }

	void modify_edata(int data) { medata = data; }

	Test operator+ (const Test& other)
	{
		Test sum;
		sum.mx = this->mx + other.mx;
		sum.my = this->my + other.my;
		return sum;
	}
	};

int main()
{
	Test t1(10, 50.5, 0), t2(20, 60.5, 0);
	Test t3;

	t3.modify_edata(1000);
	t3.print();

	t3 = t1 + t2;

	t3.print();

	return 0;
}
Вопрос:
При написании функциональности оператора "+" мое намерение состояло бы в том, чтобы добавить несколько членов класса, но не все. То, как мы обычно пишем функцию "оператор+", перезапишет все члены класса, потому что мы создаем локальный объект в "операторе+ ()". Можем ли мы избежать этого? Как в этом случае сохранить значения других членов класса?

Что я уже пробовал:

Пытаюсь понять, как это делается. Может быть, так оно и работает. Нужно подтверждение.

3 Ответов

Рейтинг:
26

CPallini

См. "Бинарные арифметические операторы" раздел о перегрузка оператора - cppreference.com[^] для руководства.


Member 13508014

Я читал раздел "двоичные арифметические операторы" перегрузки операторов - cppreference.com[^].
Когда мы пишем a = b + c, согласно статье, здесь " b " также будет изменено, не так ли.

CPallini

Нет, копия б кресла WHILL быть изменены.

Maciej Los

5ed!

CPallini

Спасибо, Мацей.

Member 13508014

Да. Копия Б будет изменена. Я с этим согласен.

Но, думаю, мой вопрос здесь не понят.

Мой вопрос заключается в том, что в "a = b + c" давайте предположим, что объект "a" создается немного долго, и его состояние теперь изменяется, и когда я вызываю "a = b + c", я ожидаю, что операция сложения произойдет только с несколькими членами, и они будут изменены. Другой член объекта "a", для которого операция "+" не имеет смысла, должен быть таким же, как и до вызова "a = b + c".

CPallini

Возможно, я действительно неправильно понял ваш первоначальный вопрос.
Если вы спрашиваете, стирается ли "t3.edata" в
t3 = t1 + t2;
значит, это правильно да, это правильно: это так по семантике оператора присваивания (t3 должно быть точно суммой t1 и t2).

Member 13508014

Да. Я тоже понял и согласен с тем, что точка Т3 должна быть точно суммой Т1 и Т2. Спасибо CPallini за то, что вы нашли время ответить на мой вопрос.

CPallini

Добро пожаловать.

Рейтинг:
20

steveb

Существует три правила написания двоичного арифметического оператора:
1. Вы также должны написать составной оператор, += в вашем случае.
2. Ваш составной оператор должен возвращать ссылку

MyClass & MyClass::operator+=(const MyClass &rhs) {
    ...
    return *this;
  }


3. Определите свои двоичные арифметические операторы, используя составные операторы присваивания:

const MyClass MyClass::operator+(const MyClass &other) const {
    return MyClass(*this) += other;
  }


Stefan_Lang

хороший Совет. Но самая важная его часть должна быть отмечена отдельно: оператор+ должен быть объявлен как функция-член const! (ОП забыл это сделать)

Maciej Los

5ed!

Рейтинг:
10

Stefan_Lang

Это звучит так, как будто вы пытаетесь объединить два вида объектов в один: один, который имеет интуитивно понятную концепцию суммирования, и другой, который этого не делает. Тем не менее они каким-то образом связаны с тем, что вы хотите иметь их внутри общего ... контейнер.

Я бы предложил отделить ваши "аддитивные данные" от "пользовательских данных" следующим образом:

class MyValues {
  int mx;
  float my;
public:
  MyValues(int x, float y) : mx(x), my(y) {}
  MyValues(const MyValues& other) : mx(other.mx), my(other.my) {}
  MyValues& operator +=(const MyValues& other) {
    mx += other.mx;
    my += other.my;
    return *this;
  }
  MyValues operator+(const MyValues& other) const {
    return MyValues(*this)+=other;
  }
};
class MyData {
  int mdata;
public:
  MyData(int data) : mdata(data) {}
  MyData(const MyData& other) : mdata(other.mdata) {}
  void set(int data) { mdata = data; }
  int data const ( return mdata; }
};
class MyClass {
  MyValues mvalues;
  MyData mdata;
public:
  MyClass(int x, float y, int data) : mvalues(x, y), mdata(data) {}
  void addValues(const MyClass& other) {
    mvalues += other.mvalues;
  }
};

Это позволяет отделить функциональность пользовательских данных от функциональности числовых данных.


Maciej Los

5ed!