C++中友元的详解及其作用介绍

目录
  • 概述
  • 友元
  • 普通的友元函数
  • 友元成员函数
  • 友元类
  • 总结

概述

类的友元函数 (friend) 是定义在类外部, 但是有权限访问类的所有私有 (private) 成员和保护 (protected) 成员.

友元

我们先来复习一下公有成员和私有成员的概念:

  • 公有成员 (public) : 在类外可以访问
  • 私有成员 (private): 只有本类中的函数可以访问

友元 (friend) 可以访问与其有好友关系的类中的私有成员 (有限制的共享).

友元包括友元函数和友元类:

  • 友元函数: 如果在本类以外的其他地方定义的函数, 在类体重用 friend 进行声明. 此函数就称为本类的有元函数, 友元函数可以访问这个类中的私有成员
  • 友元类: 类 A 将另一个类 B 声明为其友元类, 友元类 B 中的所有函数都是 A 类的友元函数, 可以访问 A 类中的所有成员

普通的友元函数

Time 类:

#ifndef PROJECT2_TIME_H
#define PROJECT2_TIME_H

class Time {
private:
    int hour;
    int minute;
    int second;
public:
    Time();
    Time(int, int, int);
    friend void display(Time &);  // display是Time类的friend函数
};

#endif //PROJECT2_TIME_H

Time.cpp:

#include <iostream>
#include "Time.h"
using namespace std;

Time::Time() : hour(0), minute(0), second(0) {}

Time::Time(int h, int m, int s) : hour(h), minute(m), second(s) {}

void display(Time &t) {
	// display不是Time类的成员函数, 但是可以引用Time中的私有成员
    cout << t.hour << ":" << t.minute << ":" << t.second << endl;
}

main:

#include "Time.h"
#include <iostream>
using namespace std;

int main() {

    Time t1(8, 8, 8);
    display(t1);

    return 0;
}

友元成员函数

Time 类:

#ifndef PROJECT2_TIME_H
#define PROJECT2_TIME_H

class Date;  // 对Date类进行提前引用声明
class Time {
private:
    int hour;
    int minute;
    int second;
public:
    Time();
    Time(int, int, int);
    void display(Date &d);
};

#endif //PROJECT2_TIME_H

Date 类:

#ifndef PROJECT2_DATE_H
#define PROJECT2_DATE_H

#include "Time.h"

class Date {
private:
    int year, month, day;
public:
    Date(int, int, int);
    friend void Time::display(Date &d);
};

#endif //PROJECT2_DATE_H

Time.cpp:

#include <iostream>
#include "Time.h"
#include "Date.h"
using namespace std;

Time::Time() : hour(0), minute(0), second(0) {}

Time::Time(int h, int m, int s) : hour(h), minute(m), second(s) {}

void Time::display(Date &d) {
    cout << d.year << "年" << d.month << "月" << d.day << "日" <<endl;
    cout << hour << ":" << minute << ":" << second << endl;
}

main:

#include "Time.h"
#include "Date.h"
#include <iostream>
using namespace std;

int main() {

    Time t1(8, 8, 8);
    Date d1(2021, 5, 6);
    t1.display(d1);

    return 0;
}

输出结果:

2021年5月6日
8:8:8

我们可以发现 display 不是 Date 类的成员函数, 但是可以引用 Date 中的私有成员.

友元类

Time 类:

#ifndef PROJECT2_TIME_H
#define PROJECT2_TIME_H

class Date;  // 对Date类进行提前引用声明
class Time {
private:
    int hour;
    int minute;
    int second;
public:
    Time();
    Time(int, int, int);
    void display(Date &d);
};

#endif //PROJECT2_TIME_H

Date 类:

#ifndef PROJECT2_DATE_H
#define PROJECT2_DATE_H

#include "Time.h"

class Date {
private:
    int year, month, day;
public:
    Date(int, int, int);
    friend class Time;  // 友元类
};

#endif //PROJECT2_DATE_H

总结

  • 如果在本类以外的地方定义了一个函数在类体中用 friend 对其进行声明, 此函数就称为本类的友元函数
  • 友元函数可以访问这个类中的私有成员
  • 友元函数可以是不属于任何类的非成员函数, 也可以是其他类的成员函数
  • 一个函数可以被多个类声明为 friend, 这样就可以引用多个类中的私有数据.

友元的性质:

  • 友元的关系是单向的而不是双向的
  • 友元的关系不能传递

友元的优缺点:

  • 优点: 有助于数据共享, 提高程序效率
  • 缺点: 破坏了封装原则, 不利于信息隐藏

我们在使用友元的时候, 应当时刻考虑友元的缺点. 如果能用公共成员函数解决就不必用友元.

到此这篇关于C++中友元的详解及其作用介绍的文章就介绍到这了,更多相关C++友元内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c++友元函数与友元类的深入解析

    友元函数和友元类的需要:类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性.另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率. 为了解决上述问题,提出一种使用友元的方案.友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面

  • C++友元函数与拷贝构造函数详解

    一.友元函数 1.友元函数概述: (1)友元函数是定义在一个类外的普通函数. 友元函数和普通函数的定义一样;在类内必须将该普通函数声明为友元. (2)友元函数不是成员函数. 不能通过对象来调用,而是直接调用;友元函数可以访问类的公有.受保护以及私有成员,但是必须通过对象.对象指针或者对象引用来访问. 2.友元函数的声明: friend 返回值类型 函数名(参数表); 在类中只需要将这个声明放置在公有部分即可. class Point { double x, y; public: Point(){

  • 关于C++友元函数的实现讲解

    友元函数是一种特殊的函数,它必须要在类中进行声明,但其本身并不是类的成员函数,但友元函数可以访问类的私有成员变量. 友元函数的好处: 1.实现类之间的数据共享 2.提高程序运行效率,方便编程 友元函数的坏处: 1.破坏数据的隐蔽性和类的封装性 2.降低了程序的可维护性 所有,友元函数应当谨慎的去使用它. 实例: #include <iostream> #include <cstring> using namespace std ; class Student { private :

  • 关于C++友元类的实现讲解

    C++中的友元既可以实现友元函数,也可以实现友元类,也就是说一个类也可以作为另外一个类的友元.当作为一个类的友元时,它的所有成员函数都是另一个类的友元函数,都可以访问另一个类的私有或者公有成员. 请看实例: #include <iostream> #include <cstring> using namespace std ; //声明教师类 class Techer ; //学生类 class Student { private: string name ; int age ;

  • C++友元(Friend)用法实例简介

    相对于Java而言,友元是C++中特有的一种元素,很多教材上对其介绍的相对较少,因此初学的时候往往不能很快掌握,本文总结了友元的用法和一些注意的地方,供大家参考借鉴.希望能对初学C++的朋友起到一点帮助作用. 操作步骤: 1)在MyFriend类中,将Father类定义成友元 2)写一个Son类继承自Father类 3)在Father类和Son类的构造函数中分别创建MyFriend对象,并定义其内部的三个变量 4)在MyFriend类的构造函数中创建Father对象,并定义其内部的三个变量 结果

  • C++中友元的详解及其作用介绍

    目录 概述 友元 普通的友元函数 友元成员函数 友元类 总结 概述 类的友元函数 (friend) 是定义在类外部, 但是有权限访问类的所有私有 (private) 成员和保护 (protected) 成员. 友元 我们先来复习一下公有成员和私有成员的概念: 公有成员 (public) : 在类外可以访问 私有成员 (private): 只有本类中的函数可以访问 友元 (friend) 可以访问与其有好友关系的类中的私有成员 (有限制的共享). 友元包括友元函数和友元类: 友元函数: 如果在本类

  • C++中运算符重载详解及其作用介绍

    目录 概述 函数重载 运算符重载 C++ 的运算符 重载运算符的规则 成员函数实现 Complex 加法 运算符重载的方法 多种实现方法 实现 operator+= 三种运算符重载函数 成员函数实现 友元函数实现 输出结果 重载单元运算符 例子 重载二元运算符 例子 重载 I/O 插入运算符 << 提取运算符 >> 总结 概述 运算符重载 (Operator Overloading) 函数重载 重载: 将同一名字重新赋予新的含义. 函数重载: 对一个函数赋予新的含义, 使之实现新功

  • C/C++ 中memset() 函数详解及其作用介绍

    memset 函数是内存赋值函数,用来给某一块内存空间进行赋值的: 包含在<string.h>头文件中,可以用它对一片内存空间逐字节进行初始化: 原型为 : void *memset(void *s, int v, size_t n); 这里s可以是数组名,也可以是指向某一内在空间的指针: v为要填充的值: n为要填充的字节数: 例子: struct data { char num[100]; char name[100]; int n; }; struct data a, b[10]; me

  • C/C++中字符串流详解及其作用介绍

    目录 概述 字符串流 理解字符串流 输出字符串对象 输入字符串流对象 输入输出字符串流对象 案例一 案例二 字符数组 vs 文件 总结 概述 文件流类和字符串流类都是 ostream, istream 和 iostream 类的派生类, 因此对它们的操作方法是基本相同的. 字符串流 文件流 字符串流 概念 文件流是以外存文件为输入输出对象的数据流 字符串流也 称为内存流, 以内存中用户定义的字符数组 (字符串) 为输入输出的对象 相关流类 ifstream, ofstream 和 fstream

  • C/C++中命名空间(namespace)详解及其作用介绍

    目录 概述 命名空间 命名空间的作用 自定义命名空间 命名空间成员的方法 案例 概述 命名空间 (namespace) 可以帮助我们区分不同库中相同名称的函数, 类, 变量等. 使用了命名空间即定义了上下文. 命名空间就是定义了一个范围. 命名空间 为了解决 C++ 标准库中的标识符与程序中的全局标识符之间以及不同库中的所有标识符之间的命名冲突. 标准 C++ 库的所有标识符都定义在一个名为 std 的命名空间中. 在程序中用到 C++ 标准库时, 使用 std 作为限定. 我们在写 "Hell

  • C/C++中数据类型转换详解及其作用介绍

    目录 概述 不同类型数据间的转换 隐式类型转换 强制类型转换 自己声明的类型转换 转换构造函数 类型转换函数 案例 应用 概述 在日常的开发中, 我们经常会用到数据类型转换, 所以我们要对数据类型转换有一定的了解. 不同类型数据间的转换 在 C++ 中, 某些标准类型的数据之间可以自动转换. 隐式类型转换 隐式类型转换: 由 C++ 编译系统自动完成的, 我们无需干预. 例如: int main() { int a = 6; a = a + 3.5; cout << a << en

  • C++中继承(inheritance)详解及其作用介绍

    概述 面向对象程序设计中最重要的一个概念是继承 (inheritance). 继承允许我们依据另一个类来定义一个类, 这使得创建和维护一个应用程序变得更统一. 这样做也达到了重用代码功能和提高执行效率的效果. 类的概念 一个类中包含了若干数据成员和成员函数. 不同的类中的数据成员和成员函数各不相同. 但是有时两个类的内容基本相同. 例如: 继承的概念 继承 (inheritance) 就是在一个已存在的类的基础上建立一个新的类. 已存在的类: 基类 (base class) 或父类 (fathe

  • C++中指针的详解及其作用介绍

    目录 概述 指向对象的指针 指向对象数据成员的指针 this 指针 this 指针的作用 this 指针的实现 概述 指针 (pointer) 是一个变量, 其指为另一个变量的地址. 即内存位置的直接地址. 指向对象的指针 在建立对象时, 编译系统会为每一个对象分配一定的存储空间, 以存放其成员. 我们可以定义一个指针变量, 用来存放对象的指针. 例如: Time time1; Time *p; // 定义指针, 格式: 类名 *对象指针名 p = &time1; // 将指针指向Time类对象

  • C++中模板(Template)详解及其作用介绍

    目录 概述 函数模板 类模板 模板类外定义成员函数 类库模板 抽象和实例 概述 模板可以帮助我们提高代码的可用性, 可以帮助我们减少开发的代码量和工作量. 函数模板 函数模板 (Function Template) 是一个对函数功能框架的描述. 在具体执行时, 我们可以根据传递的实际参数决定其功能. 例如: int max(int a, int b, int c){ a = a > b ? a:b; a = a > c ? a:c; return a; } long max(long a, l

  • C/C++中虚函数详解及其作用介绍

    目录 概述 使用方法 关联 静态关联 动态关联 案例1 未使用虚函数 使用虚拟类 案例2 总结 概述 虚函数 (virtual function) 指可以被子类继承和覆盖的函数. 使用方法 基类声明成员函数为虚函数的方法: virtual [类型] 函数名([参数表列]) 注: 在类外定义虚函数时, 不需再加 virtual. 虚函数的特点: 提高程序扩充性: 派生类根据需要可以进行函数覆盖 成员函数被声明为虚数后, 其派生类中覆盖函数自动称为虚函数 若虚函数在派生类中未重新定义, 则派生类简单

随机推荐