目录
前言
一、友元函数
二、友元类
三、友元成员函数
总结
前言
在类创建对象,类的成员存在权限,默认有些成员不能在类外进行访问,但是有特定情况想要访问对象的私有成员,允许一种特殊的访问方式(在类外也可以访问到对象的私有成员),叫做友元访问,如何能够实现友元访问功能呢,一般我们通过友元函数,友元类,或则友元成员函数来实现,通过友元访问,能够无视private和protected,直接能够访问到不能类外访问的属性,下面我们将来分开描述各种友元来访问类中的属性的实现,以及修改类中值的操作
一、友元函数
友元函数(friend function)是C++中一种特殊的函数,它可以访问类的私有成员(private)和保护成员(protected),即使它本身不是该类的成员函数。在C++中,类通常封装了数据,使用private
和protected
访问控制来保护类的内部成员变量和函数。但有时需要让外部函数或其它类能够访问这些私有成员。此时,友元函数可以实现这一目的。
友元函数虽然能访问类的私有和保护成员,但它并不属于类的成员函数,不能通过类的对象调用它,调用时使用普通的函数调用方式。
友元函数虽然使得外部函数可以访问类的私有成员,但它也打破了类的封装性。因此,在设计时要谨慎使用友元函数,不要滥用它。
#include <iostream>class Animal {private:int age; // 动物的年龄double weight; // 动物的体重public:// 构造函数Animal(int a, double w) : age(a), weight(w) {}// 友元函数声明friend void showAnimalDetails(const Animal& animal);// 成员函数:动物的行为void eat() const {std::cout << "The animal is eating." << std::endl;}void sleep() const {std::cout << "The animal is sleeping." << std::endl;} };// 友元函数定义 void showAnimalDetails(const Animal& animal) {// 友元函数可以访问类的私有成员std::cout << "Animal Details:" << std::endl;std::cout << "Age: " << animal.age << " years" << std::endl;std::cout << "Weight: " << animal.weight << " kg" << std::endl; }int main() {// 创建一个 Animal 对象Animal lion(5, 190.5);// 调用友元函数,显示动物的详细信息showAnimalDetails(lion);// 调用动物的行为函数lion.eat();lion.sleep();return 0; }
二、友元类
友元类是指一个类将另一个类声明为友元类,允许该友元类访问它的私有和保护成员。整个友元类中的所有成员函数都可以访问另一个类的私有成员,在下面的代码当中所示:
#include <iostream>// 前向声明类 Dog class Dog;class Animal {private:int age; // 动物的年龄double weight; // 动物的体重public:// 构造函数Animal(int a, double w) : age(a), weight(w) {}// 将 Dog 类声明为友元类friend class Dog; };// Dog 类定义 class Dog {public:void showAnimalDetails(const Animal& animal) const {// 作为友元类,Dog 可以访问 Animal 的私有成员std::cout << "Animal Details (from Dog):" << std::endl;std::cout << "Age: " << animal.age << " years" << std::endl;std::cout << "Weight: " << animal.weight << " kg" << std::endl;}void bark() const {std::cout << "The dog is barking." << std::endl;}void wagTail() const {std::cout << "The dog is wagging its tail." << std::endl;} };int main() {// 创建一个 Animal 对象Animal lion(5, 190.5);// 创建一个 Dog 对象Dog myDog;// Dog 对象调用其成员函数,显示 Animal 对象的详细信息myDog.showAnimalDetails(lion);// 调用 Dog 对象的行为函数myDog.bark();myDog.wagTail();return 0; }
在这个代码当中,我们将狗这个类用friend标识,标识狗这个类是动物这个类的友元类,狗这个类中的对象可以直接使用动物这个类当中的函数,并且还能访问其私有成员变量。
三、友元成员函数
友元成员函数是指一个类的某个成员函数被另一个类声明为友元。这样,只有该成员函数有权限访问该类的私有和保护成员,而不是整个类。
#include <iostream>// 前向声明类 Dog class Dog;class Animal {private:int age; // 动物的年龄double weight; // 动物的体重public:// 构造函数Animal(int a, double w) : age(a), weight(w) {}// 将 Dog 类的 showAnimalDetails 成员函数声明为友元函数friend void Dog::showAnimalDetails(const Animal& animal); };// Dog 类定义 class Dog {public:void showAnimalDetails(const Animal& animal) const {// 作为友元成员函数,showAnimalDetails 可以访问 Animal 的私有成员std::cout << "Animal Details (from Dog's member function):" << std::endl;std::cout << "Age: " << animal.age << " years" << std::endl;std::cout << "Weight: " << animal.weight << " kg" << std::endl;}void bark() const {std::cout << "The dog is barking." << std::endl;}void wagTail() const {std::cout << "The dog is wagging its tail." << std::endl;} };int main() {// 创建一个 Animal 对象Animal lion(5, 190.5);// 创建一个 Dog 对象Dog myDog;// 使用 Dog 对象调用 showAnimalDetails 函数,显示 Animal 对象的详细信息myDog.showAnimalDetails(lion);// 调用 Dog 对象的行为函数myDog.bark();myDog.wagTail();return 0; }
看上面的代码,我们只是将狗类中的成员函数给用friend进行了标识,表示只有这个成员函数能够访问动物类中的成员,而不是整个狗类都能访问动物类中的成员。
总结
友元访问提供了一种便利,当我们不能直接访问其他类中的私有成员时,可以设置友元来进行访问,并且还能通过友元来将其他类中的成员值进行修改;如下:
#include <iostream>// 前向声明类 Dog
class Dog;class Animal {private:int age; // 动物的年龄double weight; // 动物的体重public:// 构造函数Animal(int a, double w) : age(a), weight(w) {}// 将 Dog 类的 modifyAnimalDetails 成员函数声明为友元函数friend void Dog::modifyAnimalDetails(Animal& animal, int newAge, double newWeight);// 成员函数:显示动物的详细信息void showDetails() const {std::cout << "Animal Details:" << std::endl;std::cout << "Age: " << age << " years" << std::endl;std::cout << "Weight: " << weight << " kg" << std::endl;}
};// Dog 类定义
class Dog {public:void modifyAnimalDetails(Animal& animal, int newAge, double newWeight) const {// 作为友元成员函数,modifyAnimalDetails 可以修改 Animal 的私有成员animal.age = newAge;animal.weight = newWeight;}void bark() const {std::cout << "The dog is barking." << std::endl;}void wagTail() const {std::cout << "The dog is wagging its tail." << std::endl;}
};int main() {// 创建一个 Animal 对象Animal lion(5, 190.5);// 显示 Animal 对象的初始详细信息std::cout << "Initial ";lion.showDetails();// 创建一个 Dog 对象Dog myDog;// 使用 Dog 对象调用 modifyAnimalDetails 函数来修改 Animal 对象的详细信息myDog.modifyAnimalDetails(lion, 7, 210.0);// 显示 Animal 对象的修改后的详细信息std::cout << "After modification by Dog: ";lion.showDetails();// 调用 Dog 对象的行为函数myDog.bark();myDog.wagTail();return 0;
}