目录
前言
一、友元函数
二、友元类
三、友元成员函数
总结
前言
在类创建对象,类的成员存在权限,默认有些成员不能在类外进行访问,但是有特定情况想要访问对象的私有成员,允许一种特殊的访问方式(在类外也可以访问到对象的私有成员),叫做友元访问,如何能够实现友元访问功能呢,一般我们通过友元函数,友元类,或则友元成员函数来实现,通过友元访问,能够无视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;
}