5.友元运算符重载
Posted smallqizhang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5.友元运算符重载相关的知识,希望对你有一定的参考价值。
1.友元函数
定义:在C++中,一个普通函数是不可以直接访问类中的任意成员的,但是如果把这个函数声明为友元函数,那么这个函数就可以访问类中的所有成员。
优点:能够不受限制地访问类中的任意成员,在一定程度上可以提高程序的执行效率。
缺点:打破类的封装性。
声明格式:friend 返回值数据类型 函数名(参数类别) 可以在类中的任意位置声明
(1)普通函数声明为友元函数
class Student{ friend void student_info(Student& student_info); public: Student(){} ~Student(){} protected: private: } //声明函数为友元函数 void student_info(Student& stu){}
(2)一个类的成员函数可以声明为另一个类的友元函数(一般不建议使用)
class Cat;//引用形参,指针,引用 class Person{ public: Person(Cat& c):caty(c){} ~Person(){} void show(); private: Cat &caty; } class Cat { public: Cat(){} ~Cat(){} private: friend void show(); }
(3)还可以把一个类A声明为另一个类B的友元类,这样友元类A的成员函数就可以访问类B的私有成员了。
class Cat{ public: Cat(){} ~Cat(){} private: friend class Person;//声明为友元类 } class Person{ }
友元类的特点:友元类是单向的,不能被继承。
2.运算符重载
算术运算符"+","-"只能用于基本数据类型(包括指针)的运算,但是对于自定义数据类型(Complex)是没有办法运算的。运算符重载之后,就可以对自定义数据类型进行运算了。
注意事项:
(1)运算符重载只能对已有的运算符进程重载
(2)不能重载的运算符(::,sizeof,?:,.*,->*,.)
(3)运算符重载不能改变运算符原来的特性和规则
双目运算符的重载
(1)成员函数重载 运算符的左值是函数调用者,右值是函数参数
Complex A,B; Complex C=A+B;//重载函数 A.Complex(B) Complex operator+(Complex B){ Complex C; C.real=this->real+B.real; C.image=this->image+B.image; return C; }
(2)友元函数重载
Complex A,B; Complex C=A+B;//operator(A,B) //友元函数重载,不是成员函数,所以没有this指针 Complex operator+(Complex& A,Complex& B) { Complex C; C.real=A.real+B.real; C.image=A.image+B.image; return C; }
由于友元函数不是成员函数,没有this指针,所以左右值都要通过参数传递,左值是第一个参数,右值是第二个参数。
(3)输出重载 实质上也是友元重载
operator& operator<<(ostream& out,Complex &C){ out<<"("<<","<<C.image<<")"<<endl; return out; }
单目运算符重载 A++是先用了再+1,++A是先+1再用
(1)成员函数重载
A++的情况
Complex operator++(int){ //保存原来的值 Complex old=*this;//==>old(*this) this->real+=1; this->image+=1; return lod; }
++A的情况
Complex& operator++(){ this->real+=1; this->image+=1 return *this; }
(3)括号 [],{}重载
(1)成员函数重载
重载[]
int &operator[](int i){ return this->array[i]; }
重载()
coid operator()(){ cout<<"()()()()()"<<endl; }
(4)数据类型转换重载
(1)成员函数 格式:operator 数据类型 (){return 要转换的类型数据}
operator int*() { return array } operator int() { return length; } Sqlist sq(10); int a=sq;//operaotr int(); int *p=sq;//operator int*();
转换为自定义的数据类型
class B{ public: B(){} ~B(){} }; class A{ public: A(){} ~A(){} operator B(){return b;} B b; } int main() { A a; B b=a; return 0; }
(5).赋值运算符重载
class Data{ public: Data(){ cout<<"Data()"<<endl; p=new int(32); } ~Data(){cout<<"~Data()"<<endl;} Data(Data& d){cout<<"Data(Data& d"<<endl;} int data; int *p; //重载赋值运算符 Data& operator(Data& d) { if(this!= &d)//避免拷贝给自己 { this->data=d.data; memcpy(this->p,d,p,sizeof(int)); } return *this; } } int main() { Data a; a.data=123; Data b=a; Data c; c=a; cout<<a.data<<" "<<b.data<<" "<<c.data<<endl; cout<<a.p<<" "<<b.p<<" "<<c.p<<endl; return 0; }
2.构造函数隐式转换
class Number{ public: Number(int n=0):num(n){} void show(){cout<<this->number}; private: int num; } //使用 Number ynum=123;//构造函数隐式转换 ynum.show();
想要避免隐式转换,就在构造函数前面添加"explicit"关键字
PS:有哪里写错写漏了,请指正,互相学习。
以上是关于5.友元运算符重载的主要内容,如果未能解决你的问题,请参考以下文章
C++入门不能重载为友元函数的4个运算符(=, ->, [ ], ( ))