`

C++][基础知识4] 友元函数

    博客分类:
  • C++
 
阅读更多
四 友元函数
为了强调类的数据封装性,常将一些关键成员设为私有访问特性或保护访问特性。这样,在类的外面只能通过类的成员函数来访问这些成员,有时会觉得类的这种特性很不方便。但是,如果将这些成员的访问特性设为公有的,则又失去了类的封装性。为了解决这个矛盾,VC++中引入了友元函数的概念。对于某一个类来说,该类的友元函数可以是一个不属于任何类的普通函数,也可以是另一个成员函数。
 1 友元函数的说明及使用
如果在一个类中使用关键字friend对一个不属于该类的外部函数进行说明,则外部函数就成为该类的友元函数,它可以访问该类的任何成员。例如:
#include<iostream.h>
class A{
	int a,b;
	friend void print(A);
public:
	A(int x,int y)
	{a=x;b=y;}
	friend void show(A *p)
	{
		cout<<p->a<<'\n';
		cout<<p->b<<'\n';
	}
};
void print(A t)
{
	cout<<t.a<<'\n';
	cout<<t.b<<'\n';
}
void main()
{
	A a1(10,20);
	print(a1);   //A行
	show(&a1);   //B行
}

在类中可以只对友元函数进行原型说明(如上面的友元函数print()),也可以在类中对友元函数进行定义(如上面的友元函数show())。
友元函数不是类的成员函数,所以在友元函数中对类的对象的成员进行访问时必须指明该成员所属的对象。
同样,由于友元函数不是类的成员,所以,友元函数是不受类中访问特性的限制的,如上例中的友元函数print(),虽然它是与私有成员一起说明的,但它的使用与友元函数show()一样不受类的访问权限的限制,并且在调用这些友元函数时也是直接调用,如程序中的A行和B行不能写成A.print(a1)和A.show(&a1)。
由于友元函数破坏了类的封装性,所以,它的使用有可能对程序带来一些不利的影响。通常,在友元函数中不修改类的成员数据而只用于读取类成员的数据。
 2 友元成员函数及友元类
一个类放入友元函数可以是另一个类的成员函数,并且,如果将一个类说明为某类的友元类,则友元类的所有成员函数均为该类的友元函数。
#include<iostream.h>
class C;
class A{
	int a,b;
public:
	A(int x,int y)
	{a=x;b=y;}
	void addA(C &t);   //A行 
};
class B{
public :
	void sub(C &t);    //B行
	void show(C t);
};
class C{
	int a,b;
public:
	C(int x,int y)
	{a=x;b=y;}
	friend void A::addA(C &t); //说明A的成员函数为友元
	friend class B;            //说明类B为友元
};
void A::addA(C &t)
{
	t.a+=a;
	t.b+=b;
}
void B::sub(C &t)
{
	t.a--;
	t.b--;
}
void B::show(C t)
{
	cout<<t.a<<'\t'<<t.b<<'\n';
}
void main()
{
	A a1(10,20);
	B b1;
	C c1(30,40);
	b1.show(c1);
	a1.addA(c1);
	b1.show(c1);
	b1.sub(c1);
	b1.show(c1);
}

其中,由于类A和类B的成员函数中均用到了类C的对象,所以类C在类A和B之后定义,则在使用它之前给出类C的说明,并且,程序中用到类C的对象的几个成员函数的函数体也只能在类C之后定义(如程序中的A,B,C行的函数)。当然,如果类C在类A和B之前定义,则无上述必要。
上述程序在类C中将类B说明为友元类,则表示类B的所有成员函数均为类C的友元函数。但这种友元关系是不可逆的,即类B为类C的友元并不代表类C也为类B的友元。
上述程序运行结果:
30 40
40 60
39      59
 3 抽象类与友元函数
由于某些特殊需要,如果设计类的构造函数为私有或保护访问特性,则在正常情况下该类不能用来生成对象,但如果将某函数定义为该类的友元,则可以在该函数中生成该类的对像。如:
#include<iostream.h>
class A{
	int a,b;
protected:
	A(int x,int y)
	{a=x;b=y;}
	friend A fun();
	friend void main();
};
A fun()
{
	A t(10,20);
	return t;
}
A a1(fun());
void main()
{
	cout<<a1.a<<'\t'<<a1.b<<'\n';
}

程序中类A的构造函数为保护访问特性,正常情况下不可以产生对象。但可以通过其友元函数来返回一个对象,这个返回的对象用来拷贝出一个全局作用域的对象a1(程序中的A行)。同时,由于主函数也为类A的友元,所以在主函数中可以输出对象a1的成员函数。程序运行输出如下:
10   20
分享到:
评论

相关推荐

    C++ 基础知识总结_终稿_1241

    C++ 基础知识总结目录C++ 面试基础知识总结 1位域 5C 实现 C++ 类 7friend 友元类和友元函数 8:: 范围解析运算符 9enum 枚举类型

    C++100天经典实战系(含大量案例源码及通俗讲解教程,effective_c++、STL、综合能力全面提升)

    1、C++基础学习 友元函数与友元类、引用与指针那些事、深入浅出C++虚函数的vptr与vtable、宏那些事、范围解析运算符那些事、从初级到高级的enum那些事、纯虚函数和抽象类、volatile、virtual、using、union、this、...

    C++入门经典(第9版) ([美]Walter Savitch著) 中文pdf完整扫描版[302MB]

    第2章 C++基础知识 第3章 更多的控制流程 第4章 过程抽象和返回值的函数 第5章 所有子任务的函数 第6章 I/O流:对象和类入门 第7章 数组 第8章 字符串和向量 第9章 指针和动态数组 第10章 定义类 第11章 类中的友元...

    传智播客_C++基础课程讲义_v1.0.7

    6.1友元函数 6 6.2友元类 6 7强化训练 6 1 static关键字强化训练题 6 2 数组类封装 6 3小结 6 8运算符重载 6 8.1概念 6 8.2运算符重载的限制 6 8.3运算符重载编程基础 6 8.4运算符重载提高 6 8.5运算符重载在项目...

    c++面向对象基础知识

    这些语法知识,均是C++语言中最基础和常见的语法知识。在介绍语法规则时,通常使用示例形式来说明语法要求。限于形式与篇幅,难以保证涉及所有的细节。尽管如此,本文档中的示例可以作为大家使用相应语法知识编写...

    ——太棒了——c++学习笔记和常见面试知识点,c++ 11特性,包括多态原理,虚表,移动语义,友元函数,符号重载,完美转发,函数指针,智能指针,常量和静态的,数组指针和指针数组,结构内存对齐,枚举和联盟关键字等等,还新添了其他算法和计算机基础的难点,力求简洁清晰- nwpuhq / AwesomeCpp

    ——太棒了——c++学习笔记和常见面试知识点,c++ 11特性,包括多态原理,虚表,移动语义,友元函数,符号重载,完美转发,函数指针,智能指针,常量和静态的,数组指针和指针数组,结构内存对齐,枚举和联盟关键字等等,还新添了...

    C++入门指南-v2.4.pdf

    二、C++基础入门 16 2.1 C++类和对象 17 2.2 C++命名空间 18 2.3 std标准命名空间 20 2.4 C++新增的标准输入输出方法(cin和cout) 22 2.5 C++规定的变量定义位置 24 2.6 C++新增的布尔类型(bool) 24 2.7 C++ 新增的...

    C++课程设计-健身俱乐部管理

    《健身俱乐部会员管理》主要对健身俱乐部的员工与会员信息进行管理。将俱乐部人员分为员工和会员,员工分为经理、训练经理、销售经理、...友元函数 重载 多继承 √ √ √ √ √ √ √ √ √ √ √ √ √

    c++期末复习题

    c++复习题,包含了各种类型的题其中包括对类,析构函数,构造函数,友元函数,的基础知识和综合应用

    C++实现图形管理.zip

    通过课程设计2加深对《C++面向对象程序设计》课程所学知识的理解,熟练掌握和巩固C++语言的基本知识和语法规范,掌握C++语言的基础知识,理解面向对象系统的封装性、继承性和多态性:熟练使用C语言中的函数、数组、...

    C++程序设计技能百练(code+exe)

    第1课讲解C++基础知识;第2课讲解数据类型和控制结构;第3课讲解函数;第4课讲解数组和指针;第5课讲解引用与结构;第6课讲解类和对象;第7课讲解堆、构造函数与拷贝构造函数;第8课讲解静态成员、友元与模板;第9课...

    C++类的相关知识

    详细讲诉了C++中有关类的基础知识,构造函数与析构函数、静态数据成员和静态函数成员、const对象和const函数、友元、对象指针和对象引用的有关知识。

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    第1章 C++基础 1 1.1 C++简介 1 1.1.1 C++语言的起源 1 1.1.2 C++与面向对象的程序设计 1 1.1.3 C++的特点 2 1.1.4 C++术语 2 1.1.5 C++程序示例 2 1.2 变量、表达式及赋值语句 4 1.2.1 标识符 4 1.2.2 ...

    C++初学者指南(原版)

    第 1 章:C++ 基础知识 此模块将向您介绍 C++,包括其历史、设计理念以及几个最重要的功能。此模块简要概述几个 C++ 功能,包括 C++ 程序的一般形式、一些基本控制语句和运算符。它不会介绍太多细节,而会重点介绍对...

    易学C++电子书 C++入门

    第一篇介绍了面向过程的程序设计,主要有基本语句、语法基础、函数机制和数据类型等内容。第二篇介绍了一些实用编程技巧,内容包括阅读代码、调试程序和简单的编程思想。第三篇介绍了面向对象的程序设计,主要有类和...

    C++Builder 6.0设计师之路 pdf版

    还提供了上百个如何在vcl环境下使用c++ builder功能的技巧、具有实践性的建议以及数百个可以立即运行的重要解决方案的详细代码,内容主要涉及以下几个方面:标准c++基础知识、vcl库、windows窗体、图形编程、多线程...

    Visual C++ 2005入门经典.part08.rar (整理并添加所有书签)

    7.5.2 类的友元函数 7.5.3 默认复制构造函数 7.6 this指针 7.7 类的const对象 7.7.1 类的const成员函数 7.7.2 类外部的成员函数定义 7.8 类对象的数组 7.9 类的静态成员 7.9.1 类的静态数据成员 7.9.2 类的静态函数...

    Visual C++ 2005入门经典.part04.rar (整理并添加所有书签)

    7.5.2 类的友元函数 7.5.3 默认复制构造函数 7.6 this指针 7.7 类的const对象 7.7.1 类的const成员函数 7.7.2 类外部的成员函数定义 7.8 类对象的数组 7.9 类的静态成员 7.9.1 类的静态数据成员 7.9.2 类的静态函数...

    C++Primer第四版英文版

    本书针对的是C++初学者,书中从C语言基础知识开始介绍,然后在此基础上详细阐述C++新增的特性,因此不要求读者有C语言方面的背景知识。本书可作为大中院校教授C++课程的教材,也可供初学者自学C++时使用。

Global site tag (gtag.js) - Google Analytics