友元:
目的:让一个函数或类访问另一个类的私有成员
关键字:friend
实现方式:
——全局函数做友元
——类做友元
——其他类的成员函数做友元
class Building{
//friend class frends;//使类成为友元
friend void friends::visit();//使其他类的成员函数成为友元
friend void myfriend(Buiding *buiding);//使全局函数成为友元
public:
Building(){
sit = "客厅";
bed = "卧室";
}
public:
string sit;
private:
string bed;
};
class friends{
void visit();
Building * building;
};
void friends::visit(){//成员函数类外实现
cout<<building->bed<<endl;//
}
friends::friends(){//构造函数类外实现
building = new Building;//new 什么返回什么的指针
}
void myfriend(Buiding *buiding){
int a;
a = buiding->bed;
}
int main(){return 0;}
运算符重载:
运算符重载的概念:
对已有的运算符重新定义,赋予其另一种功能
加法运算符重载
class Person{
public:
int a;
int b;
};
//通过自己写成员函数,实现两个对象相加
Person add(Person &p){
Person temp;
temp.a = this->a+p.a;
temp.b = this->b+p.b;
return temp;
}
//成员函数函数相加的另一种写法
Person operator+ (Person &p){//与上面这种唯一的区别就是函数名称是编译器取的
Person temp;
temp.a = this->a+p.a;
temp.b = this->b+p.b;
return temp;
}
//全局函数重载
Person operator+ (Person &p1,Person &p2){
Person temp;
temp.a = p1.a+p2.a;
temp.b = p1.b+p2.b;
return temp;
}
左移运算符重载
作用:可以输出自定义数据类型
class Person{
public:
int a;
int b;
};
cout<<p.a<<endl;//能输出
cout<< p <<endl;//不能输出,需要重定义
//成员函数重定义(不行)
void operator<<(cout){
operator<<(cout)等效于p<<cout//不能达到要求
}
//全局函数重定义
ostream& operator<<(ostream &cout , Person &p){//cout,cin全局只能有一个,所以只有引用
//&引用是取别名,所以cout可以是取任意名就行
cout<<"a = "<<p.a<<" b = "<<p.b;
return osteam; //不返回不能完成链式输出如:cout<<p<<"hello!!!"<<endl
}
递增运算符重载
作用:能自己可以模拟一个整型变量
class Person{//递增要区分前后置
friend ostream& operator<<(ostream &cout , Person &p);
public:
Person{
this->a = 0;
}
private:
int a;
};
ostream& operator<<(ostream &cout , Person &p){
cout<<"a = "<<p.a<<" b = "<<p.b;
return osteam;
}
//重载前置++(全局)
Person& operator++(Person &p){//返回值不带&,将拷贝构造另一个
p.a = p.a+1;
return p;
}
//重载后置++(成员)
int operator++(int){//用占位int区分前后置成员
int t = a;
a++;
return t;
}
赋值运算符重载
class Person{
public:
Person(int age){
m_age = new int(age);//把数据开辟到堆区
}
~Person(){
if(m_age != NULL)
delete m_age;
m_age = NULL;
}
int* m_age;
}
Person p1(10);
Person p2(20);
p1 = p2;//此时有两个指针指向同一个堆,所以析构会造成重复释放,崩溃
-------------------------------------------------------------
赋值重载使其深拷贝:
Person operator=(Person& p){
if(m_age ==NULL){
delete m_age;
m_age = NULL;
}
m_age = new int(*p.m_age);
return *this;//返回是为了能够连续赋值a=b=c;
}
关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象(Person p、Person m)进行对比操作
函数调用运算符()重载
():
1、函数调用运算符()也可以重载
2、由于重载后使用方式非常像函数的调用,因此成为仿函数
3、仿函数没有固定写法,非常灵活
class print{
public:
void operator()(string t){
cout<<t<<endl;
}//重载()能用许多功能
}
print p;
p("hello");//()操作符调用
print()(100,100);//print()创建一个匿名对象,用完即丢