C++中,operator<重载为何可以写在类外面,而在类里为何要加friend?

#include<iostream>usingnamespacestd;#include<string>#include<algorithm>classPerson{st... #include <iostream>
using namespace std;
#include <string>
#include <algorithm>
class Person{
string name;
int age;
public:
Person(const char* name, int age):name(name),age(age){}

// friend bool operator<(const Person& a,const Person& b){return true;}

};

bool operator<(const Person& a,const Person& b){return true;}

//就在这里,重载不是要成员函数才行么,这里operator他跟类完全没有关系啊,是一个独立的函数啊,为何类在<会去调用它?

//还有,为何写在类里,变成成员函数时,要加friend?

//还有,如果有operator=,那这个类成员函数就不用加friend,同样是运算符重载,为何这个又不用加firend?

int main()
{

Person d[3]= {Person("芙蓉",18),Person("杨强",20),Person("薇薇",16)};
sort(d,d+3);
return 0;

}
展开
 我来答
wwylele
推荐于2017-05-21 · TA获得超过2523个赞
知道小有建树答主
回答量:1037
采纳率:0%
帮助的人:1099万
展开全部

重载运算符不需要一定是成员函数,以Person和<运算符为例,下列三种写法都是正确的


//  "a<b"的重载的三种方法
//作为成员函数重载(常见)
class Person{
string name;
int age;
public:
Person(const char* name, int age):name(name),age(age){}
     bool operator<(const Person& b);

};
bool Person::operator<(const Person& b)
{
//作为成员函数时,*this即为左操作数a
...
}

//作为友元函数重载
class Person{
string name;
int age;
public:
Person(const char* name, int age):name(name),age(age){}
     friend bool operator<(const Person& a,const Person& b);

};
bool operator<(const Person& a,const Person& b)
{
...
}

//作为普通函数重载(不推荐)
class Person{
public://注意,重载运算符为普通函数时,使用到的类成员必须为public
string name;
int age;
public:
Person(const char* name, int age):name(name),age(age){}

};
bool operator<(const Person& a,const Person& b)
{
...
}
更多追问追答
追问
不对啊,我上面那个例子,如果作为成员函数,必须要加friend,否则报错。
追答

如果我没有搞错的话,你给的这段

class Person{
string name;
int age;
public:
Person(const char* name, int age):name(name),age(age){}

       friend  bool operator<(const Person& a,const Person& b){return true;}

};

等价于我写的第二种,这个重载并没有作为Person的成员函数,而仅仅是它的友元函数,只不过把函数的内容直接写在了类的里面。作为成员函数重载时,应像我写的第一种写法,不写friend,参数只写一个右操作数,且如果函数定义在外部时要写Person::

kolonse
2014-08-23 · 超过33用户采纳过TA的回答
知道答主
回答量:176
采纳率:0%
帮助的人:91.2万
展开全部

你可以不那样写,可以把它当作成员函数,加friend后只是为了说明了以下几点:

  1. 该函数是外部的一个函数,非类的成员函数

  2. 该函数内部使用该类的对象时可以访问该类的私有和保护成员


如果你把重载函数写成成员函数,而且是public属性,对于使用该操作符时其实没有差别,但是如果是保护或者私有,那么在外部你就不能使用该操作符了.以下是例子

class a

{

public:

    bool operator<(const Person& b){return true;}

};


a a1,a2;

bool bRet = a1 < a2 ; 正确


-------------------------------------------------------------------------------------

class a

{

protected:

    bool operator<(const Person& b){return true;}

};


a a1,a2;

bool bRet = a1 < a2 ; 错误


-----------------------------------------------------------------------------------------

class a

{

public:

    friend  bool operator<(const Person& a,const Person& b);//加了friend表示该函数不是成员函数了,顺便说一下 你上面的例子中,既然加了friend就不能再这里实现,所以{ return true;}是错误的写法

};

bool operator<(const Person& a,const Person& b){return true;}


a a1,a2;

bool bRet = a1 < a2 ; 正确


------------------------------------------------------------------------------------------

class a

{

protect:

    friend  bool operator<(const Person& a,const Person& b);

    int a; // 假定下面的操作符要访问 保护成员变量a 如果是保护函数也一样

};

bool operator<(const Person& a,const Person& b){ return a.a > b.a;} //这里访问了保护成员a


a a1,a2;

bool bRet = a1 < a2 ; 错误 因为函数内部访问了 保护成员a

-------------------------------------------------------------------------------------------

class a

{

    friend  bool operator<(const Person& a,const Person& b);// 这里友元了操作符函数

protect:

    int a; // 假定下面的操作符要访问 保护成员变量a 如果是保护函数也一样

};

bool operator<(const Person& a,const Person& b){ return a.a > b.a;} //这里访问了保护成员a


a a1,a2;

bool bRet = a1 < a2 ; 正确,因为该操作符被类a友元了,所以即使内部访问了类的属性也正确

追问
问题是,作为成员函数时,我上面那个例子,必须要加friend,否则报错,这是为何
追答
那是因为你的例子写法有问题,至于什么问题,你可以参考我上面的回答.
class a

{
public:
bool operator<(const Person& b){return true;}

};

a a1,a2;
bool bRet = a1 < a2 ; 正确

这个就是不加friend的例子,注意参数,这里是一个,而不是2个
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
潮汕瓜
2014-08-23
知道答主
回答量:23
采纳率:0%
帮助的人:18万
展开全部
friend 声明该函数是类的友元,可以访问私有成员,用friend可以避免用类名加点调用函数,这比较麻烦,还有friend只能在类内,不能在类外再加,否则会报错
更多追问追答
追问
问题是,作为成员函数时,我上面那个例子,必须要加friend,否则报错,这是为何
追答
不加friend就是成员函数,你在外面实现时需在函数前加类名::
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式