C++ 友元

friend

采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成
员函数一般定义为公有的,依此提供类与外界间的通信接口。

但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类
的数据成员,这时可以将这些函数定义为该类的友元函数。除了友元函数外,还有友元
类,两者统称为友元。

友元的作用是提高了程序的运行效率(即减少了类型和安全性检查及调用的时间
开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为
友元类。

#include <iostream
<think>好的,我现在需要回答用户关于C++函数和的定义及使用方法的问题。首先,我需要回忆自己关于的知识,并确保理解正确。 首先,函数是什么?根据引用中的内容,函数是一个普通函数,不属于的成员函数,但可以访问的私有和保护成员。比如在引用[1]的示例代码中,`geta`函数被声明为A的,因此可以直接访问A的私有成员a。同时,引用[3]提到函数需要在内部声明,使用`friend`关键字,然后在外定义。这一点很重要,声明函数的位置在的内部,而定义则可以在外部。 然后是意味着另一个的所有成员函数都可以访问当前的私有和保护成员。例如,如果B是A的,那么B的所有函数都能访问A的私有成员。这在引用[2]和引用[1]中都有提到,但具体的例子可能需要进一步补充。 接下来,用户可能想知道如何正确使用函数和。例如,在引用[4]中,提到了函数的定义格式,但用户需要注意函数并不是成员函数,所以定义时不需要使用作用域运算符(即不需要`名::`)。不过,这里可能存在混淆,因为引用[4]的说法可能有误,正确的函数定义应该是在外作为普通函数定义,而不是用名限定。比如引用[3]中的`showX`函数,定义时并没有使用`MyClass::`,而是直接作为全局函数定义。所以需要纠正引用[4]中的描述,可能是用户引用中的错误信息。 此外,的使用场景和注意事项也需要说明。比如,破坏了封装性,应谨慎使用。通常用于运算符重载或某些需要跨访问的情况。比如重载`<<`运算符时,常将其声明为函数,以便访问私有成员输出内容。 在回答时,需要结构清晰,分点说明函数和的定义、使用方法,并给出示例代码。同时,结合引用的内容,正确引用来源,例如引用[1]、引用[3]中的代码示例,引用[2]中的定义解释等。 还要注意用户提供的引用中有可能存在错误,需要仔细核对。例如引用[4]提到的函数定义格式是否准确,根据C++标准,函数如果是全局函数,定义时不需要名限定,而如果是另一个的成员函数作为,则定义时需要相应的名限定。所以可能需要更详细地解释这一点,避免用户误解。 最后,生成相关问题,确保问题与主题相关,能够帮助用户进一步学习,比如的优缺点、使用场景、与成员函数的区别等。</think>### C++函数与详解 #### 一、函数 1. **定义** 函数是一个**非成员函数**,但被声明为后,可以直接访问该的私有(`private`)和保护(`protected`)成员。通过在内使用`friend`关键字声明,例如: ```cpp class MyClass { private: int x; public: friend void showX(MyClass obj); // 声明函数[^3] }; ``` - **关键点**:函数不是的成员函数,没有`this`指针,需通过对象参数访问成员。 2. **用法示例** ```cpp #include <iostream> using namespace std; class A { public: A(int _a) : a(_a) {} friend int geta(A &ca); // 声明函数[^1] private: int a; }; // 定义函数(无需作用域::) int geta(A &ca) { return ca.a; // 直接访问私有成员a } int main() { A a(3); cout << geta(a) << endl; // 输出3 return 0; } ``` - **说明**:`geta()`在外定义,但能访问A的私有成员`a`[^1]。 --- #### 二、 1. **定义** 是指一个(如`B`)被声明为另一个(如`A`)的后,**B的所有成员函数**均可访问A的私有和保护成员。 ```cpp class A { friend class B; // 声明[^2] private: int secret; }; class B { public: void revealSecret(A &obj) { cout << obj.secret; // 直接访问A的私有成员 } }; ``` 2. **使用场景** - 当两个需要紧密协作(如数据结构和其迭代器)时。 - 需跨操作私有数据,但又不希望暴露给全局函数。 --- #### 三、注意事项 1. **封装性破坏** 机制破坏了封装性,过度使用会导致代码耦合性高,应谨慎使用[^3]。 2. **单向性** 关系是单向的。例如,若`B`是`A`的,`A`不自动成为`B`的。 3. **不可继承** 关系不可继承,子不会自动成为父。 --- #### 四、典型应用场景 1. **运算符重载** 例如重载`<<`运算符实现自定义输出: ```cpp class Point { private: int x, y; public: friend ostream& operator<<(ostream &os, const Point &p); }; ostream& operator<<(ostream &os, const Point &p) { os << "(" << p.x << ", " << p.y << ")"; // 访问私有成员 return os; } ``` 2. **跨协作** 如树(`Tree`)与节点(`Node`),节点可能需要访问树的私有成员。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可能只会写BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值