C++友元函数

一、概述

在 C++ 中,友元函数(Friend Function)是一个能够访问类中私有成员和保护成员的函数,即使它不是该类的成员。友元函数在某些情况下非常有用,例如当两个类需要相互访问私有成员时,或者需要某个函数访问类的私有数据,但又不想将该函数作为类的成员。

友元函数的特点

  1. 访问权限:友元函数可以访问类的所有成员,包括私有成员和保护成员。
  2. 非成员函数:友元函数不是类的成员函数,但它可以在类的内部访问私有和保护成员。
  3. 定义和声明:友元函数需要在类内部使用 friend 关键字声明,但实际定义可以在类外部进行。
  4. 作用范围:友元函数不受类的访问控制限制,但其作用范围依然在其定义所在的命名空间内。

二、友元函数的声明和定义

1.声明友元函数
  • 在类的内部声明友元函数,并使用 friend 关键字。
  • 友元函数声明的格式如下:
  • class MyClass {
    private:
        int data;
    
    public:
        // 声明友元函数
        friend void printData(const MyClass& obj);
    };
    
    2.定义友元函数
  • 友元函数的定义和普通函数一样,可以在类的外部进行。
  • 友元函数定义的格式如下:
void printData(const MyClass& obj) {
    std::cout << "Data: " << obj.data << std::endl;
}
3.使用友元函数
  • 友元函数可以像普通函数一样使用,并且可以访问类的私有成员和保护成员。
MyClass obj(42);
printData(obj); // 调用友元函数,输出:Data: 42

三、友元函数的使用场景

友元函数
  • 访问权限:友元函数可以访问类的所有成员,包括私有成员和保护成员。这是友元函数最显著的特点和优势。
  • 声明方式:友元函数必须在类的定义中使用 friend 关键字声明。
#include <iostream>

class MyClass {
private:
    int data;

public:
    MyClass(int value) : data(value) {}

    // 声明友元函数
    friend void printData(const MyClass& obj);
};

// 定义友元函数
void printData(const MyClass& obj) {
    std::cout << "Data: " << obj.data << std::endl;
}

int main() {
    MyClass obj(42);
    printData(obj); // 友元函数可以访问私有成员
    return 0;
}
成员函数
  • 访问权限:成员函数只能访问所属类的成员(包括私有成员、保护成员和公有成员)。成员函数根据其访问修饰符(public、protected、private)可以访问不同的成员。
  • 声明方式:成员函数在类的内部声明,并可以在类的内部或外部定义。
#include <iostream>

class MyClass {
private:
    int data;

public:
    MyClass(int value) : data(value) {}

    // 成员函数
    void printData() const {
        std::cout << "Data: " << data << std::endl;
    }
};

int main() {
    MyClass obj(42);
    obj.printData(); // 成员函数可以访问私有成员
    return 0;
}
普通非成员函数
  • 访问权限:普通的非成员函数不能直接访问类的私有成员和保护成员,除非通过公有接口或使用友元机制。
  • 声明方式:普通非成员函数在类外部声明和定义,与类没有直接的关联。
#include <iostream>

class MyClass {
private:
    int data;

public:
    MyClass(int value) : data(value) {}

    // 公有函数
    int getData() const {
        return data;
    }
};

// 普通非成员函数
void printData(const MyClass& obj) {
    std::cout << "Data: " << obj.getData() << std::endl;
}

int main() {
    MyClass obj(42);
    printData(obj); // 普通非成员函数通过公有接口访问私有成员
    return 0;
}

四、在不同类中使用友元函数

步骤
  1. 前向声明类:如果两个类相互需要作为对方的友元,可能需要先进行前向声明。
  2. 在目标类中声明友元函数:在其中一个类中声明另一个类的成员函数作为友元函数。
  3. 定义友元函数:在友元函数所在的类外部定义该友元函数。
#include <iostream>

// 前向声明 ClassB
class ClassB;

class ClassA {
private:
    int valueA;

public:
    ClassA(int val) : valueA(val) {}

    // 声明 ClassB 的成员函数为友元函数
    friend void showValueFromB(const ClassB& b);
};

class ClassB {
private:
    int valueB;

public:
    ClassB(int val) : valueB(val) {}

    // 声明一个成员函数
    void showValue(const ClassA& a) const;

    // 声明 showValue 为友元函数
    friend void showValueFromB(const ClassB& b);
};

// 定义 ClassB 的成员函数
void ClassB::showValue(const ClassA& a) const {
    std::cout << "Value from ClassA: " << a.valueA << std::endl;
}

// 定义友元函数
void showValueFromB(const ClassB& b) {
    std::cout << "Value from ClassB: " << b.valueB << std::endl;
}

int main() {
    ClassA a(10);
    ClassB b(20);

    b.showValue(a); // 输出 ClassA 的值
    showValueFromB(b); // 输出 ClassB 的值

    return 0;
}
类A的成员函数作为类B的友元
  • 前向声明类:为了让 ClassAClassB 互相访问,有时需要进行前向声明。
class ClassB;
  •  在目标类中声明友元函数:在 ClassA 中声明 ClassB 的成员函数 showValueFromB 为友元函数。
friend void showValueFromB(const ClassB& b);
  • 在另一个类中声明和定义成员函数:在 ClassB 中声明和定义 showValue 成员函数,用于访问 ClassA 的私有成员。
void ClassB::showValue(const ClassA& a) const {
    std::cout << "Value from ClassA: " << a.valueA << std::endl;
}
  • 定义友元函数:在类外部定义友元函数 showValueFromB,它可以访问 ClassB 的私有成员。
void showValueFromB(const ClassB& b) {
    std::cout << "Value from ClassB: " << b.valueB << std::endl;
}
  • 使用友元函数和成员函数:在 main 函数中,通过 ClassB 的成员函数 showValue 访问 ClassA 的私有成员,通过友元函数 showValueFromB 访问 ClassB 的私有成员。
int main() {
    ClassA a(10);
    ClassB b(20);

    b.showValue(a); // 输出 ClassA 的值
    showValueFromB(b); // 输出 ClassB 的值

    return 0;
}

通过这种方式,可以在不同类中声明和使用友元函数,实现跨类访问私有成员的需求。友元函数提供了访问类私有数据的灵活性,同时保持类的封装性。

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值