Перегрузка оператора оператор «+» в C ++ - PullRequest
0 голосов
/ 03 сентября 2010

Я столкнулся с проблемой с кодом ниже, который выполняется в Visual Studio 2008. Как мне написать определение функции для operator +, когда вы хотите перегрузить оператор следующим образом?

class Distance
{
    private:
        int feet,inches;
};

main......

Distance Obj, Obj1(2, 2);

Obj = 3 + Obj1; // This line here

Obj1+3 легко, но как этот один компилятор узнает, что он должен выполнять перегрузку?

Предположим, мне нужно добавить значение 3 к элементу данных feet из Obj1.

Ответы [ 4 ]

6 голосов
/ 03 сентября 2010

В нескольких ответах теперь предлагается использовать перегрузку operator+, не являющуюся членом, чтобы разрешить "добавление" объектов Distance и int.Это на самом деле не имеет смысла: что значит добавить Distance, который имеет единицу, к int, который не имеет?

Однако, имеет смысл добавить два Distance объектов вместе.Если у вас есть одно расстояние в два фута и вы добавите к нему другое расстояние в три фута, вы получите расстояние в пять футов.Это имеет смысл.

Вы можете сделать это, перегрузив operator+ между двумя Distance объектами (для простоты я предположил, что ваш Distance имеет только одно поле, содержащее дюймы. В реальном приложении выне хотелось бы иметь отдельные поля для дюймов и футов. Возможно, вы захотите использовать единицу СИ, например, метры, но это зависит от приложения и полностью зависит от вас):

Distance operator+(const Distance& lhs, const Distance& rhs)
{
    return Distance(lhs.inches + rhs.inches);
}

Это не поможет вам, однако, если вы хотите быть в состоянии сделать что-то вроде

Distance d;
d = d + 42; // assume 42 has the same units as a Distance object has

Для того, чтобы это имело смысл, вы можете использовать конструктор преобразования:

struct Distance
{
    Distance(int in = 0) : inches(in) { }
private:
    int inches;
};

Конструктор здесь является конвертирующим конструктором, поскольку он не explicit и может быть вызван с одним аргументом.Это позволяет преобразовать один int (или значение, которое неявно преобразуется в int) в объект Distance.Это позволяет вам писать

Distance d;
d = d + 42;

Почему это отличается от использования перегрузки operator+, которая принимает аргументы Distance и int?Просто: он заставляет преобразование из int в Distance иметь место перед добавлением, поэтому фактическое добавление не должно заботиться о его операндах: оно просто добавляет два расстояния вместе и позволяет конструкторам Distance иметь дело слюбые преобразования, которые необходимо выполнить.

3 голосов
/ 03 сентября 2010

Помимо перегрузки оператора +, принимающего два объекта Distance, следует избегать перегрузки operator+(const Distance &, int), как указано в других ответах.Лучше определить некоторые константы, такие как:

const Distance feet(1,0);
const Distance inch(0,1);

, а также перегрузить operator*(int, const Distance &), чтобы вы могли написать:

Distance dist = 3 * feet + 5 * inch;
Distance dist2 = dist + 2 * feet;

, что более читабельно.

3 голосов
/ 03 сентября 2010

Вам нужно написать бесплатную функцию (за пределами class):

Distance operator+(int lhs, const Distance& rhs)
{
  return ...;
}

Если ... нужно использовать приватных членов Distance, сделайте его другом в Distance.

class Distance
{
  ...
  friend Distance operator+(int lhs, const Distance& rhs);
};

Наконец, если вы хотите иметь возможность + с Distance слева, просто определите другую перегрузку operator+, как указано выше, но с Distance в качестве первого аргумента.

Все это говорит, я бы избегал делать то, что вы, кажется, делаете. Как пользователь вашего Distance класса, я не знаю, прибавит ли то, что вы делаете, 3 фута, 3 дюйма или 3 метра. Если вы не собираетесь использовать единицы СИ (метры), то не следует допускать сложение с не Distance значениями.

1 голос
/ 03 сентября 2010

Обычно оператор такой формы будет объявлен как:

Distance operator+(int lhs, const Distance& rhs) {
  // Assuming the int value represents feet
  return Distance(rhs.feet + lhs, rhs.inches);
}

Возможно, вы также захотите определить симметрию:

Distance operator+(const Distance& lhs, int rhs) {
  // Assuming the int value represents feet
  return Distance(lhs.feet + rhs, lhs.inches);
}

Кроме того, я предлагаю вам прислушаться к совету Джеймса Макнеллиса - ваша работа будет упрощена, если у вас будет только один член, представляющий длины в одной единице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...