1

C++ 重载运算符同时作为成员和函数?我正在尝试在这里设置运算符重载。

在每种情况下,我都没有将 operator+ 重载为朋友和成员的问题。但是,当我尝试同时将 + 运算符作为朋友重载和将朋友作为成员重载时,我得到了错误。

这里有点困惑。我可能会尝试做一些甚至没有意义的事情?请检查我的代码,看看我是否可以解决。情况 3 是产生错误的情况。谢谢!

CASE1重载为朋友: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; }

CASE1作为朋友重载: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&amp;, const Time&amp;);
void Show() const; };

CASE1重载为朋友: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 &amp; t1, const Time&amp; 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"; }

CASE2作为成员重载:Source.cpp / Time.h / Time.cpp Source.cpp // 相同

时间.h

const Time operator+(const Time&amp;) const;  // declaration

时间.cpp

const Time Time::operator+(const Time&amp; 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 // 相同

时间.h

friend const Time operator+(const Time&amp;) ;  // declaration

时间.cpp

friend const Time operator+(const Time&amp; t) {
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum; }  // function definition
4

1 回答 1

1

当您为您的类型提供运算符重载时,您所做的是提供一个函数以在运算符出现在代码中时调用。当只能调用一个并且无法选择时,提供两个定义是没有意义的。

也就是说,您不应该同时拥有成员函数和自由函数重载。

接下来的事情,实际上可能是你的困惑是什么意思friend。当您提供朋友声明时,您声明了一个自由函数并授予该函数访问您的私有成员的权限。它是一个自由函数,因此没有隐含的this参数,因此:

class X {
   friend X operator+(X const &);
};

将声明一个重载,operator+它接受一个类型的参数X const&并返回一个类型的对象X。顺便说一句,这是一个有效的运算符,而不是您要重载的运算符(它是一元operator+,如X x; +x;)。回到上一段,它声明了一个自由函数,而不是一个成员函数,没有隐含this的,就像你声明的那样:

class X {};
X operator+(X const &);

并且因为没有隐含的thisminutes并且hours它们本身在该函数内部没有意义并且将无法编译。(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());
}

不涉及友谊。

于 2013-03-16T01:33:37.977 回答