【学习笔记】C++之友元
一、友元函数
//Example1.
/*===============================================================
* Copyright (C) 2021 All rights reserved.
*
* 文件名称:friend.cpp
* 创 建 者:RiSK
* 创建日期:2021年08月10日
* 描 述:
*
* 更新日志:
*
================================================================*/
using namespace std;
#include <iostream>
class Demo
{
public:
Demo(int x,int y);
void setVal(int x,int y);
int getVal();
friend int add(Demo &obj);//声明该函数为友元函数
private:
int x;
int y;
static int z;
};
int Demo::z=15;
Demo::Demo(int x,int y):x(x),y(y)
{
cout << __func__ << ":" << __LINE__ <<endl;
}
void Demo::setVal(int x,int y)
{
this->x = x;
this->y = y;
}
int Demo::getVal()
{
return x;
}
int add(Demo &obj)//友元函数在类体之外的定义
{
Demo::z = 17;//z 为静态的成员 与对象无关联
// z == 17;
return obj.x + obj.y;
}
//友元函数:
// 1、成员函数声明之前使用 friend 修饰,定义时不需要
// 2、友元函数在类体之外定义时,就像普通函数定义一样,不能有 类名::
// 3、友元函数打破了类的封装和隐藏,就不再是类的成员函数
// 4、友元函数打破了类的封装,意味着在该函数体当中可以通过该类对象去访问 该类的私有成员(在该友元函数体中,没有任何的权限限制)
int main()
{
Demo obj(3,5);
obj.setVal(1,3);
//cout << obj.add() <<endl;//错误,友元函数不是类的成员函数,不能通过对象调用
//cout << Demo::add() <<endl;
cout << add(obj) << endl;//友元函数的调用
return 0;
}
1、成员函数声明之前使用friend修饰,定义时不需要
friend int add(Demo &obj);//声明该函数为友元函数
int add(Demo &obj)//友元函数在类体之外的定义
{
Demo::z = 17;//z 为静态的成员 与对象无关联
return obj.x + obj.y;
}
2、友元函数在类体之外定义时,就像普通函数定义一样,不能有 类名::
int add(Demo &obj)//友元函数在类体之外的定义
{
Demo::z = 17;//z 为静态的成员 与对象无关联
return obj.x + obj.y;
}
3、友元函数打破了类的封装和隐藏,就不再是类的成员函数
int add(Demo &obj)//友元函数在类体之外的定义
{
Demo::z = 17;//z 为静态的成员 与对象无关联
//z = 17;//错误,友元函数不再是类的成员函数
return obj.x + obj.y;
}
//cout << obj.add() <<endl;//错误,友元函数不是类的成员函数,不能通过对象调用
//cout << Demo::add() <<endl;//错误,友元函数不是类的成员函数,亦不能通过作用域访问
4、友元函数打破了类的封装,意味着在该函数体当中可以通过该类对象去访问 该类的私有成员(在该友元函数体中,没有任何的权限限制)
Demo obj(3,5);//定义obj对象并初始化
obj.setVal(1,3);//设置值
cout << add(obj) << endl;//友元函数的调用
二、友元类
//Example2.
/*===============================================================
* Copyright (C) 2021 All rights reserved.
*
* 文件名称:friend.cpp
* 创 建 者:RiSK
* 创建日期:2021年08月10日
* 描 述:
*
* 更新日志:
*
================================================================*/
using namespace std;
#include <iostream>
class A
{
public:
A(int x):x(x){}//构造函数
private:
int x;
friend class B;//说明B类是A类的友元类,也就是A将B当朋友,可以声明在任何权限下。
static int y;//定义静态成员变量
};
int A::y = 13;//初始化A类中y静态成员变量
class B
{
public:
void showMsg(A &obj)
{
cout << A::y <<endl;
cout << obj.x <<endl;
}
friend class C;//说明C类是B类的友元类,也就是B将C当朋友,可以声明在任何权限下
private:
static int x;
};
int B::x = 15;
class C
{
public:
void prnmsg()
{
cout << B::x << endl;
//cout << A::y << endl;//友元关系不具备传递性
A obj(4);
B::showMsg(obj);
}
};
int main()
{
A obj(5);
B obj1;
obj1.showMsg(obj);
}
1、如果B是A的友元类,那么B类中所有成员 都会打破A类的封装
class B
{
public:
void showMsg(A &obj)
{
cout << A::y <<endl;//在B类的成员函数中,可以直接通过 A::成员名 访问A类静态成员
cout << obj.x <<endl;在B类的成员函数中,可以通过A类对象访问 A类的任何成员
}
friend class C;//说明C类是B类的友元类,也就是B将C当朋友,可以声明在任何权限下
private:
static int x;
};
2、友元关系不能被继承、友元关系是单向的、友元关系不具备传递性
class C
{
public:
void prnmsg()
{
cout << B::x << endl;
//cout << A::y << endl;//友元关系不具备传递性
A obj(4);
B::showMsg(obj);
}
};
转载请标明出处