C++ 友元

1.定义:

1.概念:

友元 friend 机制允许一个类授权其他的函数访问它的非公有成员。友元声明以关键字 friend 开头 ,它只能出现在类的声明中, 它们不受其在类体中的 public private 和 protected 区的影响.。

2.注意
1.一个普通函数作为类的友元,那么在当前函数中就可以通过对象访问类的私有或者保护成员
  注意:这个函数只能在外部定义,在当前类中引用即可
2.一个类的成员函数作为另外一个类的友元
  注意:成员函数建议放在类外定义
3.一个类A作为另外一个类B的友元类,则A的所有的成员函数就可以访问B的私有数据成员或者保护

3.友元的分类:
友元分为外部函数友元, 成员函数友元,类友元。

友元的声明通常放在类的定义中,位于`public`、`protected`和`private`之外。声明的语法如下:

class FriendClass; // 前向声明,表示FriendClass是一个类,但不定义其成员
class TargetClass {
public:
    // 公有成员和函数声明
 
private:
    // 私有成员和函数声明
 
    friend class FriendClass; // FriendClass成为TargetClass的友元
};

在上面的代码中,`FriendClass`成为了`TargetClass`的友元,从而可以访问`TargetClass`中的私有成员。

除了友元类,我们还可以将一个全局函数声明为类的友元。全局函数在声明时要加上类的作用域限定符:

class TargetClass {
public:
    // 公有成员和函数声明
 
private:
    // 私有成员和函数声明
 
    friend void friendFunction(TargetClass& obj); // friendFunction成为TargetClass的友元

下面是一个友元函数的示例:

class TargetClass;
 
class FriendClass {
public:
    void friendFunction(TargetClass& obj); // 声明TargetClass为友元类
 
    void normalFunction(TargetClass& obj) {
        // 友元函数可以访问TargetClass的私有成员
        int x = obj.privateVar;
    }
};
 
class TargetClass {
public:
    TargetClass(int val) : privateVar(val) {}
 
private:
    int privateVar;
 
    friend void FriendClass::friendFunction(TargetClass& obj); // 声明friendFunction为友元函数
};
 
void FriendClass::friendFunction(TargetClass& obj) {
    // 友元函数可以访问TargetClass的私有成员
    int x = obj.privateVar;
}

在上述代码中,`FriendClass`声明了一个友元函数`friendFunction`,并将`TargetClass`声明为友元类。这样一来,`friendFunction`函数就能够访问`TargetClass`中的私有成员`privateVar`。

当我们将一个类的成员函数声明为另一个类的友元成员函数时,这个函数将能够访问目标类中的私有成员,类似于友元函数的行为。友元成员函数是一种在目标类中声明其他类的成员函数为友元的特殊情况。

以下是一个友元成员函数的示例:

class FriendClass;
 
class TargetClass {
private:
    int privateVar;
 
public:
    TargetClass(int val) : privateVar(val) {}
 
    // 友元成员函数,声明FriendClass的成员函数为友元
    friend void FriendClass::accessPrivateVar(TargetClass& obj);
};
 
class FriendClass {
public:
    void accessPrivateVar(TargetClass& obj) {
        // 友元成员函数可以访问TargetClass的私有成员
        int x = obj.privateVar;
    }
};

在上述代码中,`FriendClass`的成员函数`accessPrivateVar`被声明为`TargetClass`的友元成员函数。因此,`FriendClass`的成员函数`accessPrivateVar`可以直接访问`TargetClass`中的私有成员`privateVar`。

值得注意的是,友元成员函数和其他成员函数之间并没有明显的区别,它们都遵循成员函数的规则和语法。唯一的区别在于友元成员函数被声明为其他类的友元,因此它们可以访问目标类中的私有成员。

友元成员函数的使用场景与其他友元类似,可以用于操作符重载、多个类之间的交互和单元测试等情况。然而,同样要注意友元成员函数可能会打破封装性和数据隐藏原则,因此需要谨慎使用,并确保在需要的情况下使用友元成员函数。

4. 友元类
友元类是指一个类被声明为另一个类的友元。友元类可以访问目标类的私有成员,类似于允许其他类访问自己私有成员的特权。

下面是一个友元类的示例:

class FriendClass {
public:
    void accessTarget(TargetClass& obj) {
        // 友元类可以访问TargetClass的私有成员
        int x = obj.privateVar;
    }
};
 
class TargetClass {
public:
    TargetClass(int val) : privateVar(val) {}
 
private:
    int privateVar;
 
    friend class FriendClass; // FriendClass成为TargetClass的友元类
};

在上述代码中,`TargetClass`将`FriendClass`声明为自己的友元类。因此,`FriendClass`的成员函数`accessTarget`可以访问`TargetClass`中的私有成员`privateVar`。

5. 友元与封装性
封装是面向对象编程的重要特性之一,它强调将数据和对数据的操作封装在一个单元(类)中,同时通过公有接口控制对数据的访问。友元机制可能会打破这种封装性,因为它允许其他类或函数直接访问目标类的私有成员。

虽然友元在某些情况下很有用,但过度使用友元可能导致代码失去封装性和难以维护。因此,在使用友元时应该谨慎考虑,确保只有在必要的情况下使用它。

6. 友元的使用场景
虽然友元应该谨慎使用,但在一些特定的情况下,它可以提供便利并简化代码的设计。

以下是一些常见的友元使用场景:

6.1. 操作符重载

在C++中,操作符重载是一种强大的特性,允许我们自定义类对象之间的操作。当我们想要直接访问另一个类的私有成员时,可以将操作符重载函数声明为友元。

class Complex {
private:
    double real;
    double imaginary;
 
public:
    Complex(double r, double i) : real(r), imaginary(i) {}
 
    // 友元函数,实现Complex类对象与另一个类对象的相加
    friend Complex operator+(const Complex& lhs, const AnotherClass& rhs);
};
 
class AnotherClass {
private:
    int someValue;
 
public:
    AnotherClass(int val) : someValue(val) {}
 
    // 非成员函数,因为它需要访问AnotherClass的私有成员
    friend Complex operator+(const Complex& lhs, const AnotherClass& rhs) {
        double realPart = lhs.real + rhs.someValue;
        double imagPart = lhs.imaginary;
        return Complex(realPart, imagPart);
    }
};

在上述代码中,`Complex`类声明了一个友元函数`operator+`,用于实现`Complex`类对象与`AnotherClass`类对象的相加操作。通过友元机制,`operator+`函数能够访问`AnotherClass`的私有成员`somValue`。

7. 友元的局限性
尽管友元在某些情况下非常有用,但也有一些限制和局限性:

- 友元关系不可传递:如果A是B的友元,B是C的友元,那么A并不会成为C的友元。
- 友元关系不可继承:派生类不继承基类的友元,除非它显式地声明自己的友元。
- 友元是单向的:如果类A是类B的友元,不一定意味着类B也是类A的友元。
- 友元不影响类的访问控制:友元只影响类的访问权限,但并不改变成员的实际可见性。

8. 总结
友元是C++中一种特殊的访问控制机制,允许一个类或函数访问另一个类的私有成员。友元可以通过在目标类中声明其他类或函数来实现,它在某些情况下可以提供便利并简化代码的设计,如操作符重载、单元测试和多个类之间的交互。

然而,友元应该谨慎使用,因为它可能打破封装性和数据隐藏原则。在使用友元时,需要仔细权衡利弊,确保代码的设计和可维护性不受影响。友元关系是单向且不可传递的,不影响类的继承和访问控制,因此需要谨慎考虑其使用场景。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值