关于友元

本文介绍了C++中的友元概念,包括友元函数和友元类的定义及使用方法。阐述了如何通过友元提高程序运行效率,同时讨论了友元带来的封装性和隐藏性的破坏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

友元函数和友元类    

  采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元函数 :       友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,

其格式如下:      friend  类型 函数名(形式参数);      友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。      一个函数可以是多个类的友元函数,只需要在各个类中分别声明。      友元函数的调用与一般函数的调用方式和原理一致。

友元类 :       友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。             当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:      friend class 类名;      其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。      例如,以下语句说明类B是类A的友元类:      class A      {             …      public:             friend class B;             …      };      经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。      使用友元类时注意:            (1) 友元关系不能被继承。             (2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。            (3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

<think>嗯,用户让我详细罗列计算机二级C++中关于友元函数、静态函数和虚函数的考点。首先,我得回忆一下这三个概念的基本定义和它们在C++中的作用。友元函数不是类的成员,但可以访问类的私有和保护成员,对吧?然后是静态函数,属于类本身而不是类的实例,所以不需要对象就能调用。虚函数则是实现多态的关键,允许子类重写父类的方法。 接下来,我需要考虑用户可能的考试需求。计算机二级考试通常会涉及语法、使用场景、注意事项以及常见错误点。比如友元函数的声明方式,静态函数能否访问非静态成员,虚函数表和动态绑定的机制等。这些都是常见的考点。 用户可能需要明确的条目,每个函数的特点、区别、使用例子以及易错点。比如友元函数需要在类内声明,但定义在类外;静态函数没有this指针,所以只能访问静态成员;虚函数必须有virtual关键字,且在派生类中重写时参数列表要一致。 还要注意对比这三者之间的不同,比如友元函数和成员函数的区别,静态函数和普通成员函数的区别,虚函数和普通虚函数的区别。可能还需要提到纯虚函数和抽象类,因为这也是虚函数相关的重要内容。 另外,考试中可能会出现代码阅读题,让考生指出错误或写出输出结果。比如给出一个包含友元函数调用的代码,或者静态函数访问非静态成员的错误示例,或者虚函数在继承体系中的调用情况。 还要考虑用户可能的理解难点,比如友元函数破坏了封装性,为什么还要使用它?静态函数的内存分配时机?虚函数表的实现原理等。虽然考试可能不会深入到实现细节,但基本概念还是需要掌握。 最后,整理这些考点时,要分点列出,每个函数单独作为一个大点,下面再分小点讲解定义、特点、注意事项、示例和易错点。确保结构清晰,便于用户复习和记忆。</think>以下是计算机二级C++考试中关于友元函数、静态函数、虚函数的核心考点整理,按知识点分层解析: --- ### 一、友元函数(Friend Function) #### 1. 核心定义 - 友元函数**不是类的成员函数**,但可访问类的所有成员(包括私有和保护成员) - 需在类内用 `friend` 关键字声明,定义在类外部 #### 2. 关键考点 - **声明格式**: ```cpp class A { private: int data; public: friend void showData(A obj); // 友元声明 }; ``` - **使用场景**:运算符重载、跨类数据访问 - **注意事项**: - 友元关系**不可继承** - 友元函数**没有this指针** - 破坏封装性(高频考点) #### 3. 易错示例 ```cpp class B { friend void func(); }; void func() { cout << data; // 错误!无法直接访问非静态成员 } ``` --- ### 二、静态函数(Static Member Function) #### 1. 核心特性 - 属于**类本身**而非对象,可通过类名直接调用 - 无`this`指针,只能访问静态成员 #### 2. 考试重点 - **声明方式**: ```cpp class Counter { static int count; public: static int getCount() { return count; } }; ``` - **调用方法**: ```cpp Counter::getCount(); // 正确 Counter obj; obj.getCount(); // 正确但不推荐 ``` - **内存特性**: - 静态函数在程序启动时初始化 - 与普通函数的区别:不能声明为`const`/`volatile` #### 3. 典型错误 ```cpp static void print() { cout << non_static_var; // 错误!不能访问非静态成员 } ``` --- ### 三、虚函数(Virtual Function) #### 1. 核心机制 - 实现**运行时多态**,通过虚函数表(vtable)实现动态绑定 - 必须通过**基类指针/引用**调用才能体现多态性 #### 2. 高频考点 - **声明规范**: ```cpp class Base { public: virtual void show() { cout << "Base"; } }; ``` - **覆盖规则**: - 派生类函数必须与基类虚函数**同名、同参数、同返回类型** - `override` 关键字(C++11)可显式声明覆盖 #### 3. 进阶知识 - **纯虚函数**: ```cpp virtual void draw() = 0; // 抽象类 ``` - **虚析构函数**: ```cpp virtual ~Base() {} // 避免派生类析构不彻底 ``` #### 4. 易错场景 ```cpp Base* p = new Derived(); p->show(); // 正确调用派生类版本 Base obj = *p; obj.show(); // 错误!发生切片,调用基类版本 ``` --- ### 四、对比总结表 | 特性 | 友元函数 | 静态函数 | 虚函数 | |---------------------|------------------|-------------------|-------------------| | 所属关系 | 非成员函数 | 类成员 | 类成员 | | 访问权限 | 全权限访问 | 仅静态成员 | 常规访问权限 | | 内存分配 | 独立函数 | 类加载时分配 | 对象包含vptr | | 多态支持 | 不支持 | 不支持 | 支持 | | 典型应用场景 | 运算符重载 | 工具函数/计数器 | 接口抽象 | --- ### 五、真题考点预测 1. 给出类定义代码,要求指出友元函数声明错误 2. 分析含有虚函数调用的代码输出结果 3. 静态函数访问非静态成员导致的编译错误判断 4. 虚函数表相关选择题(如sizeof含虚函数类的对象大小) 建议结合具体代码实例进行对比练习,重点理解三种函数的存储特性、访问权限和运行时行为差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值