2013-02-17 4 views
1

У меня есть следующий код для перегрузки операторов + и + = соответственно для класса Date. Оператор + был успешно перегружен, и он примет целое число n и увеличит количество объектов Date на n дней. Это делается путем применения функции next_day n раз.Перегрузка оператора + =

inline Date operator+(Date d, int n) 
{ 
    for(char j=1; j<=n; j++){ 
     d=d.next_day(d); 
    } 
    return d; 
} 
inline Date operator+=(Date d, int n) 
{ 
    Date p=d+n; 
    return p; 
} 

Перегруженный оператор +, я использую его для определения перегрузки + =. Но, несмотря на отсутствие ошибок при компиляции, когда я использую перегруженный + =, это не имеет никакого эффекта.

Вот мой main.cpp:

#include <iostream> 
#include "Date.h" 
using namespace std; 

int main() { 

Date Initialday = Date (12,1,2012); 

Initialday+=1; 
cout <<"Next day = "<< Initialday <<endl; 

return 0; 
} 

Выполнение основной функции по-прежнему дает мне 12/1/2012 вместо 12/2/2012. Что я делаю не так? Примечание. Я уже перегрузил < < для вывода объектов Date в читаемом формате, поэтому я не думаю, что это проблема.

ответ

3

Простое исправление заключается в том, чтобы взять объект Date по ссылке, изменить его и вернуть его по ссылке. Это ожидаемое поведение operator+=.

inline Date& operator+=(Date &d, int n) 
{ 
    d = d + n; 
    return d; 
} 

Однако реализовать operator+= с точки зрения operator+ это в обратном направлении. Это должно быть наоборот. operator+= должен действовать на членов объекта, меняя их напрямую. Затем operator+ должны быть реализованы с точки зрения, что:

inline Date& operator+=(Date& lhs, int rhs) 
{ 
    ... // code here to modify lhs directly 

    return lhs; 
} 

inline Date operator+(Date lhs, int rhs) 
{ 
    return lhs += rhs; 
} 
+0

большое спасибо! Я согласен, это несколько назад, но в этом случае оба + = и + казались одинаково простыми, потому что я уже определил функцию next_day и подумал, что могу использовать его. и я предполагаю, что в качестве новичка мне показалось более интуитивным определение + сначала! –

+0

только ради изучения, могу ли я спросить, почему следующее не будет работать? 'inline Date & operator + = (Date & d, int n) { Дата p = d + n; return p; } ' Он дает мне сообщение об ошибке, в котором говорится, что локальная переменная p была автоматически возвращена. Что это значит? –

+0

@PatrickJane: Вопрос не в том, что он более или менее прямолинейный, чем другой. Проблема в основном - производительность. 'operator +' принимает два объекта и делает из них совершенно отдельный объект. Но нет причин, по которым 'operator + =' должен был бы создать новый объект. Путем реализации 'operator + =' в терминах 'operator +', вы копируете объект, изменяете копию, а затем копируете копию обратно в исходный объект. Это две ненужные копии, когда все, что нужно сделать, это просто изменить исходный объект. –

2

Основная проблема заключается в том, что ваш += создает новый объект Date и возвращает его. Это неправильная семантика, плюс вы не присваиваете это возвращаемое значение чему-либо. += оператор должен действовать на экземпляре оно применяется к и вернуть его по ссылке:

inline Date& operator+=(Date& d, int n) { 
    return d = d + n; 
} 

Как правило, это будет реализовано в виде функции члена с + реализованы в терминах +=:

class Date 
{ 
public: 
    Date& operator+=(int n) { 
     // perform whatever operation is required using 
     // the state of the instance. 
     return *this; 
    } 
}; 

inline Date operator+(Date lhs, int rhs) { 
    return lhs += rhs; // calls member += 
} 

чистейший способом было бы обеспечить класс продолжительности времени, а также осуществлять все операторы в терминах Date и TimeDuration:

struct TimeDuration { .... }; 

class Date 
{ 
public: 
    Date& operator+= (const TimeDuration& rhs) { .... } 
}; 
inline Date operator+(Date lhs, const TimeDuration& rhs) { return lhs += rhs; } 
+0

Что именно означало бы добавить две даты друг другу? –

+0

@BenjaminLindley Это означало бы, что у меня еще не было кофе. Нужен тип разницы во времени, но я думаю, что просто удалю этот бесполезный ответ. – juanchopanza

+0

@BenjaminLindley damn, принято, поэтому я должен исправить это сейчас ... – juanchopanza

Смежные вопросы