• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 简要介绍C++编程中的友元函数和友元类

简要介绍C++编程中的友元函数和友元类

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++友元函数,c++友元函数实例,c++友元类,c++友元,友元函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。现在,我们来补充介绍一个例外——友元(friend)。

fnend 的意思是朋友,或者说是好友,与好友的关系显然要比一般人亲密一些。有的家庭可能会这样处理:客厅对所有来客开放,而卧室除了本家庭的成员可以进人以外,还允许好朋友进入。在C++中,这种关系以关键宇 friend 声明,中文多译为友元。友元可以访问与其有好友关系的类中的私有成员,友元包括友元函数和友元类。如果您对友元这个名词不习惯,可以按原文 friend 理解为朋友即可。
友元函数

在当前类以外定义的、不属于当前类的函数也可以在类中声明,但要在前面加 friend 关键字,这样就构成了友元函数。友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数。

友元函数可以访问当前类中的所有成员,包括 private 属性的。

1) 将普通函数声明为友元函数。

#include<iostream>
using namespace std;
class Student{
private:
 char *name;
 int age;
 float score;
public:
 Student(char*, int, float);
 friend void display(Student &); //将display声明为友元函数
};
Student::Student(char *name, int age, float score){
 this->name = name;
 this->age= age;
 this->score = score;
}
//普通成员函数
void display(Student &stu){
 cout<<stu.name<<"的年龄是 "<<stu.age<<",成绩是 "<<stu.score<<endl;
}
int main(){
 Student stu("小明", 16, 95.5f);
 display(stu);
 return 0;
}
</div>

运行结果:

小明的年龄是 16,成绩是 95.5
</div>

请注意 display 是一个在类外定义的且没有使用 Student 作限定的函数,它是非成员函数,不属于任何类,它的作用是输出学生的信息。如果在 Student 类中未声明 display 函数为 friend 函数,它是不能引用 Student 中的私有成员 name、age、score 的。大家可以亲测一下,将上面程序中的第11行删去,观察编译时的信息。

现在由于声明了 display 是 Student 类的 friend 函数,所以 display 可以使用 Student 中的私有成员 name、age、score。但注意在使用这些成员变量时必须加上对象名,不能写成:

cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
</div>


因为 display 不是 Student 类的成员函数,默认不能使用 Student 类的成员,必须指定要访问的对象。

2) 将其他类的成员函数声明为友元函数
friend 函数不仅可以是普通函数(非成员函数),还可以是另一个类中的成员函数。请看下面的例子:

#include<iostream>
using namespace std;
class Address; //对Address类的提前引用声明 
//声明Student类
class Student{
private:
 char *name;
 int age;
 float score;
public:
 Student(char*, int, float);
 void display(Address &);
};
//声明Address类
class Address{
private:
 char *province;
 char *city;
 char *district;
public:
 Address(char*, char*, char*);
 //将Student类中的成员函数display声明为友元函数
 friend void Student::display(Address &);
};
Address::Address(char *province, char *city, char *district){
 this->province = province;
 this->city = city;
 this->district = district;
}
//声明Student类成构造函数和成员函数
Student::Student(char *name, int age, float score){
 this->name = name;
 this->age= age;
 this->score = score;
}
void Student::display(Address &add){
 cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
 cout<<"家庭住址:"<<add.province<<"省"<<add.city<<"市"<<add.district<<"区"<<endl;
}
int main(){
 Student stu("小明", 16, 95.5f);
 Address add("陕西", "西安", "雁塔");
 stu.display(add);
 return 0;
}
</div>

运行结果:

小明的年龄是 16,成绩是 95.5
家庭住址:陕西省西安市雁塔区
</div>

在本例中定义了两个类 Student 和 Address。程序第 26 行将 Student 类中的成员函数 display 声明为友元函数,由此,display 就可以访问 Address 类的私有成员变量了。

两点注意:
① 程序第4行对Address类进行了提前声明,是因为在Address类定义之前、在Student类中使用到了它,如果不提前声明,编译会报错,提示"Address" has not been declared。类的提前声明和函数的提前声明是一个道理。

② 程序中将 Student 类的声明和定义分开了,而将 Address 放在了中间,是因为 Student::display() 函数体中用到了 Address 类的成员,必须出现在 Address 类的类体之后(类体说明了有哪些成员)。

这里简单介绍一下类的提前声明。一般情况下,类必须在正式声明之后才能使用;但是某些情况下(如上例所示),只要做好提前声明,也可以先使用。

但是应当注意,类的提前声明的使用范围是有限的。只有在正式声明一个类以后才能用它去创建对象。如果在上面程序第4行后面增加一行:

Address obj; //企图定义一个对象
</div>


会在编译时出错。因为创建对象时是要为对象分配内存空间的,在正式声明类之前,编译系统无法确定应该为对象分配多大的空间。编译器只有在“见到”类体后(其实是见到成员变量),才能确定应该为对象预留多大的空间。在对一个类作了提前引用声明后,可以用该类的名字去定义指向该类型对象的指针变量或对象的引用变量(如在本例中,定义了Address类对象的引用变量)。这是因为指针变量和引用变量本身的大小是固定的,与它所指向的类对象的大小无关。

请注意程序是在定义 Student::display() 函数之前正式声明 Address 类的。这是因为在 Student::display() 函数体中要用到 Address 类的成员变量 province、city、district,如果不正式声明 Address 类,编译器就无法识别这些成员变量。

③ 一个函数可以被多个类声明为“朋友”,这样就可以引用多个类中的私有成员。
友元类

不仅可以将一个函数声明为一个类的“朋友”,而且可以将整个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。

友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员。在A类的类体中用以下语句声明B类为其友元类:

friend B;
</div>


声明友元类的一般形式为:

friend 类名;
</div>

关于友元,有两点需要说明:
友元的关系是单向的而不是双向的。如果声明了 B类是A类的友元类,不等于A类是B类的友元类,A类中的成员函数不能访问B类中的私有数据。
友元的关系不能传递,如果B类是A类的友元类,C类是B类的友元类,不等于 C类是A类的友元类。

在实际开发中,除非确有必要,一般并不把整个类声明为友元类,而只将确实有需要的成员函数声明为友元函数,这样更安全一些。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 有关C++继承与友元、继承与类型转换详解
  • 实例讲解在C++的函数中变量参数及默认参数的使用
  • 简要介绍C++编程中的友元函数和友元类
  • C++虚函数表实例分析
  • C++友元(Friend)用法实例简介
  • C++函数模板与类模板实例解析
  • C++中的friend友元函数详细解析
  • 关于C++中的友元函数的一些总结
  • C++之友元:友元函数和友元类详解
  • 解析C++中不能重载为友元函数的四个运算符

相关文章

  • 2017-05-28C++ explicit构造函数实例解析
  • 2017-05-28C语言实现在数组A上有序合并数组B的方法
  • 2017-05-28深入串的模式匹配算法(普通算法和KMP算法)的详解
  • 2017-05-28详解C语言求两个数的最大公约数及最小公倍数的方法
  • 2017-05-28深入详解C编写Windows服务程序的五个步骤
  • 2017-05-28string中c_str(),data(),copy(p,n)函数的用法总结
  • 2017-05-28C语言冒泡排序法心得
  • 2017-05-28浅谈几种常见语言的命名空间(Namespace)
  • 2017-05-28构建mfc窗体的简单示例
  • 2017-05-28手把手教你如何优化C语言程序

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 哈希表实验C语言版实现
    • C语言中字符串的内存地址操作的相关函数简介
    • C++实现四叉树效果(附源码下载)
    • C语言线性表的顺序表示与实现实例详解
    • Cocos2d-x保存用户游戏数据之XML文件是否存在问题判断方法
    • C语言中sscanf()函数的字符串格式化用法
    • C++中可以接受任意多个参数的函数定义方法(详解)
    • 深入讲解C++数据类型转换的相关函数的知识
    • 解读堆排序算法及用C++实现基于最大堆的堆排序示例
    • c语言打开文件函数使用方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有