friend友元
类的私有成员只能被类的成员直接访问,类外函数是无法直接访问的。
虽然我们可以通过添加共有函数接口来间接访问私有成员,但是这样做会导致代码的运行效率降低
友元就是在类中直接声明要 访问私有成员 的外部函数或外部类为该类的友元成员
把类外的一个普通函数声明为类的友元函数,这样这个外部函数就可以访问类的私有成员了
class Student{private:string name;int age;float score;public:Student(string name,int age,float score);friend void show(const Student &stu); //声明友元函数
};
把类A的一个成员函数声明为类B的友元函数,这样这个类A的成员就可以访问类B的私有成员了
class Student; //类的前项声明class Display{public:void show(const Student &stu);]class Student{private: string name;int age;float score;public:Student(string name,int age,float score);friend void Display::show(const Student &stu); //将类Display的show函数声明为类Student的友元函数,此时show可以访问Student中的私有成员
}Student::Student(string name,int age,float score){}void Display::show(const Student &stu){}int main(){Student stu("wangcai",4,66);Display dis;dis.show(stu);return 0;
}
}
友元类: 把类A声明为类B的友元类,这样这个A的所有成员函数都可以访问类B的私有成员了
class Display;
class Student{friend class Display;
};class Display{}
友元的特点:
不具有相互性,只具有单向行
友元不能被继承
友元不具有传递性
运算符重载
系统提供的运算符只能针对进本的数据类型完成计算(int,short,char,float,double)
运算符重载就是对已有的运算符重新定义,赋予其另一种功能,以适应不同的数据类型
格式 返回类型 operator运算符(参数)
非成员函数运算符重载
一般会将他声明为类的友元函数,这样它可以访问类的私有成员
class String{friend String operator+(const String &op1,const String &op2);};//非成员函数运算符重载
String operator+(const String &op1,const String &op2){}int main(){String str1("Hello");String str2("World");String str3 = str1 + str2;
}
成员函数运算符重载
双目运算符重载为类的成员函数时,函数只显示说明一个参数,该形参是运算符的右操作数
前置单目运算符(++/--)重载为类的成员函数时,不需要显示说明参数,即函数没有形参
后置单目运算符(++/--)重载为类的成员函数时,函数要带有一个整形(int)形参
class String {String(const char* str = NULL);String operator+(const String &op2);};String String::operator+(const String &op2){}String::String(const char* str){}int main(){String str1("Hello");String str2("World");String str3 = str1.operator+(str2);//成员函数运算符重载,第一个参数为当前对象}
单目运算符重载
class String{String &operator++();String operator++(int);}String &String::operator++(){}String String::operator++(int){}int main(){//String str3=++str1; //String str4=str2++;
}
特殊运算符重载及注意点
将一个对象赋值给另一个对象时,会调用赋值运算符重载函数
str1 = str2的本质是 str2.str = str1.str
会导致错误
如果没有手动添加,编译器会提供一个默认的赋值运算符重载函数
C++ 强制规定,赋值运算符重载函数只能定义为类的成员函数
赋值运算符重载
class String(){String &operator=(const String &obj);}String &String::operator=(const String &obj){}int main(){String str1("Hello ");String str2 = str1;str2 = str1;}
不能被重载的运算符
C++中大部分运算符都可以重载,只有一小部分不可以重载, 其中"=“和”&"不重载,编译器默认支持
重载运算符限制在C++语言中已有的运算符范围内进行重载,不能创建新的运算符
重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构
重载运算符函数不能有默认的参数,否则就改变了运算符的参数个数
重载的运算符只能是用户自定义的类型
运算符重载函数可以是成员函数的形式,友元函数形式,也可以是非成员非友元的普通函数形式