c++的类成员权限以及友元

本文深入探讨了C++中类的封装特性,包括私有、公有、保护成员的访问权限,以及友元函数和友元类的概念与应用。详细解释了类成员的访问控制和友元机制在实际编程中的意义与用途。

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

c++中类是一种抽象的数据类型,里面包含成员变量(一般定义为私有)和一些成员函数(一般定义为公有),对于用户来说不需要了解类中具体的代码,只需要知道类的功能以及如何使用就ok了。这样就实现了类数据的隐藏和封装。

类大致包含私有(private),公有(public),保护的(protected)。访问权限如下:

class默认的成员权限为private(struct默认的成员权限为public):

private:只有该类的成员函数可以访问到;

public:对任何类都是公开的;

protected:只有该类以及类的子类中的成员函数可以访问。

以上阐述的权限也有一个特殊的情况:友元函数和友元类。

如果类外的函数A需要访问类中的私有成员,我们需要在类定义时在私有或者公有的部分声明该函数;eg:

class B {

private:

...

public:

friend void A(参数);

}

也可以在private中声明。是一样的。友元并不是类的成员函数,在实现的时候不需要加“::”作用域。另外友元不能继承。特别注意友元在实现的时候不能访问类的私有成员。 

但它可以访问类对象的私有成员。

如果类C想要访问类B的所有成员,可以做如下声明:

class B{

private:

...

public:

friend class C;

}

这样类C就是B的友元类。可以访问类B中的所有成员。





<think>嗯,用户想了解C++友元函数和非友元函数的区别及使用方法。首先,我需要回顾一下友元函数的基本概念。根据引用[1],友元函数是能够访问的私有和保护成员的非成员函数。而非友元函数则没有这种权限,只能访问公有成员。 那区别方面,首先是访问权限的不同。友元函数可以访问所有成员,而非友元只能访问公有部分。然后是声明方式,友元需要在内用friend关键字声明,而非友元不需要。作用域上,友元函数虽然是全局的,但和有特殊关联;非友元如果是成员函数则属于的一部分,如果是外部函数则完全独立。 使用方法的话,友元函数需要在内部声明,然后在外部定义,不需要名限定。非友元成员函数则需要在内声明,外定义时使用作用域解析运算符。外部函数则直接定义,只能通过公有接口操作对象。 还要注意友元的使用场景,比如运算符重载或需要跨协作时。但过度使用可能破坏封装性,所以应该谨慎。用户可能想知道何时该用友元,何时不该用。比如,当某个函数需要同时访问多个的私有数据时,友元可能有用,但如果是单一的功能,可能更适合用成员函数。 另外,引用[2]提到友元成员函数的定义方式,但用户的问题集中在友元函数和非友元的区别,所以可能需要强调友元函数不是成员函数,而是被授权的普通函数。而成员函数无论是否为友元,默认都有访问权限,但友元函数作为非成员,需要显式声明。 可能用户实际遇到的问题是如何决定是否使用友元函数,或者遇到访问私有成员报错的情况。需要举例说明两种函数的不同用法,比如showX作为友元可以访问私有x,而非友元函数无法直接访问,必须通过公有方法获取。 还要注意语法细节,比如友元函数在内声明时不需要作用域,而在外部定义时也不属于。而非友元成员函数定义时需要名::前缀。外部函数完全独立,不能访问私有成员。 总结回答的结构应该分点区别,然后使用方法,最后注意事项。同时生成相关问题,比如优缺点、使用场景、如何定义等,帮助用户深入理解。</think>### C++ 友元函数与非友元函数的区别及使用方法 #### 一、核心区别 1. **访问权限** - **友元函数**:能直接访问的私有(`private`)和保护(`protected`)成员,例如引用[1]中的 `showX` 函数访问 `MyClass` 的私有成员 `x`[^1]。 - **非友元函数**: - 若为**成员函数**:默认可访问的所有成员(无论是否友元)。 - 若为**外部函数**:仅能通过公有接口(`public`)操作对象。 2. **声明方式** - **友元函数**:需在内部用 `friend` 关键字声明(如 `friend void showX(MyClass obj);`)。 - **非友元函数**: - 成员函数:直接声明在内。 - 外部函数:无需内声明。 3. **作用域** - **友元函数**:本质是全局函数,但与存在特殊关联。 - **非友元函数**: - 成员函数:属于作用域。 - 外部函数:完全独立于。 #### 二、使用方法 1. **友元函数** - **定义步骤**: ```cpp class MyClass { private: int x; public: MyClass() : x(10) {} friend void showX(MyClass obj); // 内声明友元函数 }; void showX(MyClass obj) { // 全局定义,无需作用域 std::cout << "x = " << obj.x << std::endl; // 直接访问私有成员 } ``` - **关键点**: - 友元函数定义时**不需要**名限定(如 `MyClass::`)[^2]。 - 友元函数**不继承**,子需重新声明。 2. **非友元函数** - **成员函数**: ```cpp class MyClass { public: void printX() { // 内声明 std::cout << "x = " << x << std::endl; // 直接访问私有成员 } }; ``` - **外部函数**: ```cpp void printXPublic(MyClass obj) { std::cout << "x = " << obj.getX() << std::endl; // 需通过公有接口(如getX()) } ``` #### 三、注意事项 1. **封装性**:友元函数会破坏封装,仅用于特定场景(如运算符重载、跨协作)。 2. **语法细节**:友元函数声明不受访问权限控制(可放在 `private` 或 `public` 区域)。 3. **性能影响**:友元函数可能增加耦合度,需谨慎使用。 --- §§ 相关问题 §§ 1. 友元函数在运算符重载中的应用场景是什么? 2. 如何通过友元实现多个之间的协作? 3. 友元函数与静态成员函数的区别是什么? 4. 为什么C++允许友元函数破坏封装性?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值