学习借鉴网址:
operator overloading
非成员函数重载运算符
- 定义运算符重载函数后,在参数、 运算符匹配的情况下调用运算符重载函数。
- 在以下代码调用中: f1 + f2等同于operator+(f1, f2)
注意:在非成员函数重载中,只能访问操作public成员
#include <iostream>
using namespace std;
class F{
public:
int a;
};
int operator+(F &f1, F& f2){
return f1.a + f2.a;
}
int main(int argc, char *argv[])
{
F f1;
f1.a = 1;
F f2;
f2.a = 2;
cout << f1 + f2 << endl;
return a.exec();
}
友元运算符重载
- 友元是关键字,友元运算符重载不是重载友元,而是使用友元来重载运算符
- 相对于普通运算符重载函数,友元可以访问形参类型中的私有成员
- 在双目运算符中,友元运算符重载有两个参数,友元中没有this指针
- 当一个复数与一个整数相加时,无论整数出现在左侧还是右侧,使用友元运算符重载函数都能得到很好的解决。
- 在以下代码调用中: stu + stu2等同于operator+(stu, stu2)
#include <iostream>
using namespace std;
class Student{
private:
int id;
public:
Student(int id_t){
id = id_t;
}
Student(){}
friend int operator+(Student& stu, Student& stu2);
};
int operator+(Student& stu, Student& stu2){
return stu.id + stu2.id;
}
int main(int argc, char *argv[])
{
Student stu(1);
Student stu2(2);
cout << stu + stu2 <<endl;
return 0;
}
成员函数运算符重载
- 成员函数运算符重载相对与友元运算符重载,要少一个形参,即this指针。
- 在以下代码调用中: stu2 = stu;等同于stu2.operator=(stu);
#include <iostream>
using namespace std;
class Student{
private:
int id;
public:
Student(){}
Student(int id):id(id){}
Student& operator=(Student& stu2){
this->id = stu2.id;
return *this;
}
int getId(){
return id;
}
};
int main(int argc, char *argv[])
{
Student stu(10);
Student stu2(2);
stu2 = stu;
cout << stu2.getId() << endl;
return 0;
}
总结
- C++大部分运算符既可以用成员运算符重载函数,又可以用友元运算符重载函数。
- 如果运算符所需要的操作数(尤其是第一个操作数)希望有隐式类型转换,则运算符重载必须使用友元函数,而不能使用成员函数。
- 对于单目运算符,建议选择成员函数重载
- 对于双目运算符,一般而言选择友元运算符重载函数较好
- 对于运算符”=、()、[]、->”只能作为成员函数
- 对于运算符”+=、-=、/=、*=、/=、!=、~=、%=、<<=、>>=”,建议选择成员函数重载
- 对于其他运算符,建议选择友元运算符重载函数较好
问题
在C++运算符重载这一章中一直有一个让我想不明白的问题,
赋值运算符为什么不能友元重载?在使用重载运算符时,怎么选择友元运算符重载函数和成员函数运算符重载?
我有浏览过很多博主写的文章,但仍然没有找到想要的答案,我摘录一些博主的在其他论坛、文章中的见解:
[]、()、->、=这几个运算符如果要重载,为什么必须重载为成员函数而不能重载为友元?
youyou1912:为什么呢? 因为
C++不允许全局重载这几个操作符.
C++也没有提供调用对象作为参数放进去.struct A; void operator()(A*, int);// 非法
关于C++运算符重载 成员函数和友元函数的区别
Falleyes:一楼正解,那个网址给的好牛。
全局版本的自动类型(友元)转换可以针对左右任意操作数,而成员版本(成员)必须保证左操作数已经处于正确的形式。
比如成员函数:N operator+(const N&n) const{ return N(i+n.i); //函数调用可以计算a+1,但是无法计算1+a //友元版本包括两个参数,所以可以计算a+1,也可以计算1+a }
运算符重载:成员函数与非成员函数?
If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2 into s1.operator+(s2). That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!But what if the first operand is not a class? There’s a major problem if we want to overload an operator where the first operand is not a class type, rather say double. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.