C ++ оператор перегрузки как член и функция одновременно?
Я пытаюсь настроить перегрузку оператора здесь.
У меня нет проблем с оператором + перегрузка в качестве друга и члена в каждом случае.
Но когда я пытаюсь перегрузить оператор + как друг и друг как член одновременно, я получаю ошибку.
Вид здесь запутался. Я мог бы попытаться сделать что-то, что даже не имеет смысла?
Пожалуйста, проверьте мой код и посмотрите, смогу ли я решить его.
Случай 3 — это случай, генерирующий ОШИБКИ. Спасибо!
СЛУЧАЙ 1 Перегрузка в качестве друга: Source.cpp
#include <iostream>
using namespace std;
#include "Time.h"int main () {
Time planning; Time coding(2, 40);
Time fixing(5, 55); Time total;
total = coding + fixing;
cout << "coding + fixing = ";
total.Show();
cout << endl;
cin.get(); return 0; }
СЛУЧАЙ 1 Перегрузка в качестве друга: Time.h
#pragma once
class Time
{ int hours; int minutes;
public:
Time(void);
~Time(void);
Time(int, int m = 0);
void AddMin(int);
void AddHr(int);
void Reset(int h=0, int m=0);
friend const Time operator+(const Time&, const Time&);
void Show() const; };
СЛУЧАЙ 1 Перегрузка в качестве друга: Time.cpp
#include "Time.h"#include <iostream>
using namespace std;
Time::Time(void) { hours = minutes = 0;}
Time::~Time(void) {}
Time::Time (int h, int m) { hours =h; minutes = m; }
void Time::AddMin(int m) {minutes+=m; hours+=minutes/60; minutes%= 60; }
void Time::Reset(int h, int m) {hours = h; minutes = m;}
const Time operator+(const Time & t1, const Time& t2) {
Time sum;
sum.minutes = t1.minutes + t2.minutes;
sum.hours = t1.hours + t2.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; }
void Time::Show() const
{ cout << hours << " hours, " << minutes << " minutes"; }
Вариант 2 Перегрузка в качестве члена: Source.cpp / Time.h / Time.cpp
Source.cpp
// так же
time.h
const Time operator+(const Time&) const; // declaration
Time.cpp
const Time Time::operator+(const Time& t) const {
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; } // function definition
ДЕЛО 3: ОШИБКА; пытается перегрузить оператор + как друга и члена одновременно
Source.cpp
// так же
time.h
friend const Time operator+(const Time&) ; // declaration
Time.cpp
friend const Time operator+(const Time& t) {
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; } // function definition
Когда вы предоставляете перегрузку оператора для своего типа, вы делаете предоставление функции для вызова, когда оператор появляется в коде. Не имеет смысла предоставлять два определения, когда можно вызвать только одно, и нет способа выбрать его.
То есть у вас не должно быть как функции-члена, так и перегрузки свободной функции.
Следующее, что может вызвать у вас путаницу, это то, что означает friend
является. Когда вы предоставляете декларацию друга, вы объявляете свободно функция и предоставление этой функции доступа к вашим личным членам. Это бесплатная функция, и как таковая не существует неявной this
аргумент, таким образом:
class X {
friend X operator+(X const &);
};
объявил бы перегрузку для operator+
который принимает один аргумент типа X const&
и возвращает объект типа X
, Кстати, это допустимый оператор, но не тот, который вы хотите перегрузить (это унарный operator+
, как в X x; +x;
). Возвращаясь к предыдущему абзацу, он объявляет свободную функцию, а не функцию-член, нет неявной this
как если бы вы заявили:
class X {};
X operator+(X const &);
И потому что нет неявного this
, minutes
а также hours
сами по себе не имеют смысла внутри этой функции и не смогут скомпилироваться. (The friend
ключевое слово в определении также неверно, friend
никогда не может появиться вне определения класса).
Существует некоторая путаница относительно того, friend
имеет какое-то особое значение по отношению к операторам, это не так. Это просто ключевое слово, которое влияет на спецификаторы доступа. Если вы можете реализовать оператор с точки зрения открытого интерфейса вашего типа, это не должно быть friend
на первом месте. Так что если, например, у вас были аксессоры в Time
чтобы получить часы и минуты, вы можете реализовать оператора как:
class Time { // ...
public:
Time(int hours, int minutes);
int hours() const;
int minutes() const;
};
Time operator+(Time const & lhs, Time const & rhs) {
return Time(lhs.hours()+rhs.hours(), lhs.minutes()+rhs.minutes());
}
Без дружбы.
Других решений пока нет …