C++ 基础

C++ 主页 C++ 概述 C++ 环境设置 C++ 基本语法 C++ 注释 C++ Hello World C++ 省略命名空间 C++ 标记 C++ 常量/字面量 C++ 关键字 C++ 标识符 C++ 数据类型 C++ 数字数据类型 C++ 字符数据类型 C++ 布尔数据类型 C++ 变量类型 C++ 变量作用域 C++ 多变量 C++ 基本输入/输出 C++ 修饰符类型 C++ 存储类 C++ 数字 C++ 枚举 C++ 枚举类 C++ 引用 C++ 日期和时间

C++ 运算符

C++ 运算符 C++ 算术运算符 C++ 关系运算符 C++ 逻辑运算符 C++ 位运算符 C++ 赋值运算符 C++ sizeof 运算符 C++ 条件运算符 C++ 逗号运算符 C++ 成员运算符 C++ 强制类型转换运算符 C++ 指针运算符 C++ 运算符优先级 C++ 一元运算符

C++ 控制语句

C++ 决策语句 C++ if 语句 C++ if else 语句 C++ 嵌套 if 语句 C++ switch 语句 C++ 嵌套 switch语句 C++ 循环类型 C++ while 循环 C++ for 循环 C++ do while 循环 C++ Foreach 循环 C++ 嵌套循环 C++ break 语句 C++ continue 语句 C++ goto 语句

C++ 字符串

C++ 字符串 C++ 循环遍历字符串 C++ 字符串长度 C++ 字符串连接 C++ 字符串比较

C++ 函数

C++ 函数 C++ 多函数参数 C++ 递归函数 C++ 返回值 C++ 函数重载 C++ 函数重写 C++ 默认参数

C++ 数组

C++ 数组 C++ 多维数组 C++ 指向数组的指针 C++ 将数组传递给函数 C++ 从函数返回数组

C++ 结构 &联合

C++ 结构 C++ 联合

C++ 指针

C++ 指针 C++ 解引用 C++ 修改指针

C++ 类和对象

C++ 面向对象 C++ 类 &对象 C++ 类成员函数 C++ 类访问修饰符 C++ 静态类成员 C++ 静态数据成员 C++ 静态成员函数 C++ 内联函数 C++ this 指针 C++ 友元函数 C++ 指向类的指针

C++ 构造函数

C++ 构造函数 &析构函数 C++ 默认构造函数 C++ 参数化构造函数 C++ 复制构造函数 C++ 构造函数重载 C++ 带默认参数的构造函数 C++ 委托构造函数 C++ 构造函数初始化列表 C++ 使用构造函数动态初始化

C++ 继承

C++ 继承 C++ 多重继承 C++ 多级继承

C++ 面向对象

C++ 重载 C++ 多态性 C++ 抽象 C++ 封装 C++ 接口 C++ 虚函数 C++ 纯虚函数与抽象类

C++ 文件处理

C++ 文件和流 C++ 文件读取

C++ 进阶

C++ 异常处理 C++ 动态内存 C++ 命名空间 C++ 模板 C++ 预处理器 C++ 信号处理 C++ 多线程 C++ Web 编程 C++ 套接字编程 C++ 并发 C++ 高级概念 C++ Lambda 表达式 C++ unordered_multiset

C++ 实用资源

C++ 问答 C++ 快速指南 C++ 速查表 C++ STL 教程 C++ 标准库 C++ 实用资源 C++ 讨论


C++ 友元函数

C++ 友元函数

类的友元函数定义在类作用域之外,但它有权访问类的所有私有和受保护成员。即使友元函数的原型出现在类定义中,友元函数也不是成员函数。

友元可以是函数、函数模板、成员函数,也可以是类或类模板,在这种情况下,整个类及其所有成员都是友元。

声明友元函数

要将函数声明为类的友元,请在类定义中的函数原型前加上关键字 friend,如下所示

语法

class Box {
   double width;
   
   public:
      double length;
      friend void printWidth( Box box );
      void setWidth( double wid );
};

要将 ClassTwo 类的所有成员函数声明为 ClassOne 类的友元函数,请在 ClassOne 类的定义中添加以下声明 -

friend class ClassTwo;

友元函数示例

以下是 C++ 中 Friend 函数的代码:

#include <iostream>
 
using namespace std;
 
class Box {
   double width;
   
   public:
      friend void printWidth( Box box );
      void setWidth( double wid );
};

// 成员函数定义
void Box::setWidth( double wid ) {
    width = wid;
}

// 注意:printWidth() 不是任何类的成员函数。
void printWidth( Box box ) {
    /* 由于 printWidth() 是 Box 的友元,因此它可以
    直接访问此类的任何成员 */
   	cout << "Width of box : " << box.width <<endl;
}
 
// Main function for the program
int main() {
    Box box;
    
    // 不使用成员函数设置框宽度
    box.setWidth(10.0);
    
    // 使用友元函数打印宽度。
    printWidth( box );
    
    return 0;
}

当编译并执行上述代码时,它会产生以下结果 -

Width of box : 10

访问私有成员和受保护成员

类的私有成员和受保护成员在类外部无法访问。但是,如果您想访问它们,可以使用 friend 函数。friend 函数可以直接访问类的私有成员和受保护成员。

示例

以下示例演示了如何使用 friend 函数访问类的私有成员和受保护成员:

#include <iostream>
using namespace std;

class ClassName {
 private:
  int privateData;  // 私有成员

 protected:
  int protectedData;  // 受保护成员

 public:
  ClassName() : privateData(0), protectedData(0) {}

  // 声明一个友元函数
  friend void friendFunction(ClassName& obj);
};

// 友元函数定义
void friendFunction(ClassName& obj) {
    obj.privateData = 42; 	// 访问私有成员
    obj.protectedData = 24; // 访问受保护成员
    cout << "Private Data: " << obj.privateData << endl;
    cout << "Protected Data: " << obj.protectedData << endl;
}

int main() {
  ClassName obj;
  friendFunction(obj);  // 调用好友函数
  return 0;
}

当编译并执行上述代码时,它会产生以下结果 -

Private Data: 42
Protected Data: 24

友元函数 vs 成员函数

在 C++ 中,友元函数和成员函数都用于访问和操作类的数据,但它们在作用域和用法上仍然存在显著差异。

友元函数

友元函数是使用"friend"关键字在类内部声明的非成员函数,它对类的私有成员和受保护成员具有特殊访问权限。由于它不是成员函数,因此不绑定到特定对象,不能基于对象重载,不能使用 this 指针,也不能被派生类继承。它们在类外部定义,但在类内部声明。

成员函数

而成员函数在类内部定义,并使用 this 指针进行操作。它可以访问类的所有成员(私有、受保护和公共),并且由于它与类对象绑定,因此可以被派生类重载和继承。

友元类

在 C++ 中,友元类是指可以访问另一个类的私有和受保护成员的类。当一个类将另一个类声明为友元类时,第二个类(友元类)可以直接访问第一个类的私有和受保护成员。

这个概念类似于友元函数,但这里的朋友是整个类,而不是特定的函数。

语法

以下是 C++ 中友元类的语法:

class ClassB; // ClassB 的前向声明

class ClassA {
private:
  int dataA;

public:
    // 将 ClassB 声明为 ClassA 的朋友
    friend class ClassB;
};

示例

以下示例演示了 C++ 中朋友类的示例:

#include <iostream>
using namespace std;

class ClassB; // ClassB 的前向声明

class ClassA {
 private:
  int dataA;

 public:
  ClassA() : dataA(42) {}  // 使用值初始化数
  
  据 // 将 Class 声明为 ClassA 的朋友
  friend class ClassB;
};

class ClassB {
 public:
  void showDataFromA(const ClassA& objA) {
    // 访问 ClassA 的私有成员
    cout << "Data from ClassA: " << objA.dataA << endl;
  }
};

int main() {
  ClassA objA;
  ClassB objB;

  // 使用 ClassB 访问 ClassA 的私有数据
  objB.showDataFromA(objA);

  return 0;
}