C++基础语法:友元

前言

         "打牢基础,万事不愁" .C++的基础语法的学习."学以致用,边学边用",编程是实践性很强的技术,在运用中理解,总结.

        以<C++ Prime Plus> 6th Edition(以下称"本书")的内容开展学习

引入

        友元提供了一种特别的方式,访问对象私有数据.

        友元有三种方式:友元非成员函数;友元类;友元成员函数; 

 从私有数据的访问说起        

         举例:建立一个Person类,声明年龄和姓名属性

        main.h

#include<iostream>
using namespace std;

class Person {
	string name;
	int age;
public:
	Person(const string& str,int ag):name(str),age(ag){}
	int getAge() const{ return age; }
	string getName() const{ return name; }
};

        main.cpp  //测试代码 

#include<iostream>	
#include"main.h"

int main(void) {
	Person xiaozhang("小张", 35);
	cout << "小张的年龄是:" << xiaozhang.getAge() << endl;   //通过公开的接口访问私有数据
//	cout << "小张的年龄是:" << xiaozhang.age << endl;		//无法访问私有数据
}

         ----根据"数据私有,接口公开"这个编码原则,访问对象属性必须通过public中的接口函数

友元的各种实现 

1.友元非成员函数 

        在public中定义一个打印对象信息的函数

        经典代码(在本书P394)一是使用了友元访问私有数据,二是链式调用,不影响原有的cout

        注:所谓经典代码,可以背下来的代码       

friend ostream & operator<<(ostream& os, Person person) {	//友元非成员函数定义
    //可以使用erson.name和person.age了
    os << "姓名为:" << person.name << "年龄为:" << person.age << endl;	
    return os;												//返回引用,链式调用
}

        说明:可以在同Person类的文件中定义,这里为了方便写成了内联函数. 

         测试代码,在main.cpp中添加

cout << xiaozhang;    //调用友元函数

        和接口函数的区别:用"对象.属性"取得属性值,而不是调用上面的接口函数"对象.getAge()",看起来更形象.

2.友元类

        在Person类中声明友元类

friend class Friend;        //友元类

        编写友元类

        这里用了两种方式:一是传入原始类对象引用,二是原始类对象依赖(也就是把原始类对象引用作形参传入)

class Friend {											//Person的友元类Friend
	Person& person;
public:
	Friend(Person& pe):person(pe){}
	//传入对象引用,对象.属性访问
	void print() { 
        cout <<"朋友姓名是:"<< person.name<<"," << "年龄是:" << person.age << endl;
     }
	//添加依赖,对象.属性访问
	void print2(Person& person2){ 
    cout << "朋友姓名是:" << person2.name << "," << "年龄是:" << person2.age << endl; 
    }
};

        测试代码,在main.cpp中添加

Friend xz_friend(xiaozhang);							//友元类对象
xz_friend.print();

Person laoli("老李", 45);								//友元类依赖
xz_friend.print2(laoli);

         说明:因为声明了友元类,所以在Friend类中访问Person类的属性,也是对象.属性.

3. 友元成员函数

         本书P607有相关描述,原始类和使用友元成员函数的类先后顺序有要求,需要前向声明原始类,代码如下: 1234表示顺序

class Person;						          //1原始类前向声明,为使用友元成员函数的类准备

class FriendFun {					          //2使用友元成员函数的类
	double money;
public:
	FriendFun(double mo) :money(mo) {}
	void set_age(Person& person, int ag);	  //友元成员函数不能写成内联函数,必须写在外面
};

class Person {								  //3原始类
	string name;
	int age;
public:
	Person(const string& str,int ag):name(str),age(ag){}
	int getAge() const{ return age; }
	string getName() const{ return name; }
	//声明友元成员函数
	friend void FriendFun::set_age(Person& person, int ag);
};

//4定义在类外的友元成员函数
void FriendFun::set_age(Person& person, int ag) {							
	person.age = ag;                          //对象.属性访问原始类私有数据
}

注意:

 顺序如下:1原始类前向声明→2使用友元成员函数的类声明→3原始类声明→4友元成员函数定义

 测试代码,在main.cpp中添加

//生成友元成员函数所在的类对象
FriendFun ff(5000);	
//传入原始类对象,调用友元成员函数,修改原始对象数据					               
ff.set_age(xiaozhang,30);	
//看是否改变了原始对象的数据			               
cout << "小张的年龄是:" << xiaozhang.getAge() << endl;	

友元的分析

        1.不管是哪一种友元,都是以"对象.属性"访问将其视为友元的原始类对象数据 

        2.如1所述,友元不能单独存在,必须要使用原始对象引用,他的形式可以是函数形参,也可以是传给友元类的属性.

友元的思考

        1.友元是否破坏了数据的封装性?

        不会.使用友元是为了以一种友好的方式访问私有数据.如果不使用友元,也可以通过包含对象引用,再通过接口函数来访问.和枚举一样,友元虽然不是必须的,但在某些情况下会比较方便.

        2.怎样概括友元?

        友元是一种授权.他授权其他成员函数或者非成员函数访问或者修改对象的私有属性.

小结

        对友元的一些理解和使用. 

        C++在"数据可见性"上有很多的定义,比如私有公有,命名空间,类作用域,还有这里的友元.有一种简便的写法:所有数据公开,然后根据情况调整.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重庆彭枫

你的鼓励是我创作的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值