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:有哪里写错写漏了,请指正,互相学习。
来源:https://www.cnblogs.com/smallqizhang/p/12528434.html