C++中的友元函数
时间:2020-02-23 14:29:57 来源:igfitidea点击:
C++中的"友元函数"是一类函数,可以作为类的公共函数/外部访问类的私有成员和受保护成员。
您可能想知道;这有可能吗?好吧,现代的C++说是的!
让我们看看如何在C++中使用这些函数。
C++中的友元函数
如果函数定义以friend关键字为前缀,则将函数称为友元函数。
我们不能在类外使用friend前缀,因此只能在成员函数声明中使用。
例如,如果我们想在声明中使用friend关键字,可以这样使用:
#include <iostream>
using namespace std;
class MyClass {
private:
int a, b;
public:
MyClass(int a, int b) {
//Constructor
this->a = a;
this->b = b;
}
void set_a(int val);
void set_b(int val);
int get_a() {
return a;
}
int get_b() {
return b;
}
//Declare a friend function of this class
friend void my_fun(MyClass& my_obj, int val, char option);
};
void my_fun(MyClass& my_obj, int val, char option) {
//Friend function that sets the private variables
//based on the option
if (option == 'a') {
//Set a
my_obj.a = val;
}
else {
//Set b
my_obj.b = val;
}
}
int main() {
MyClass my_obj(1, 2);
cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
//Friend functions can be accessed from outside the class!
my_fun(my_obj, 20, 'a');
my_fun(my_obj, 40, 'b');
cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
return 0;
}
其中my_fun()是MyClass的友元函数,因此它也可以访问私有成员!
注意,我们也可以从类外部访问友元函数。
上面的friend函数直接设置私有成员" a"或者" b"的值!
输出
my_obj.a = 1 and my_obj.b = 2 my_obj.a = 20 and my_obj.b = 40
友元函数可以在同一类中,甚至可以在另一类中。
但是它必须是成员函数。
让我们一一看一下这两种情况。
C++中同一类中的Friend 函数
上面的例子向我们展示了我们可以在同一个类中使用一个友元函数。
class MyClass {
private:
int a, b;
public:
MyClass(int a, int b) {
//Constructor
this->a = a;
this->b = b;
}
void set_a(int val);
void set_b(int val);
int get_a() {
return a;
}
int get_b() {
return b;
}
//Declare a friend function of this class
//within the same class itself!
friend void my_fun(MyClass& my_obj, int val, char option);
};
我们将继续处理下一种情况;当一个友元函数在另一个类中时!
实际上,这是另一个主题,称为"友元班",但是它们彼此直接相关。
C++中的友元类–另一个类中的友元函数
具有另一个类别A的友元功能的任何类别B称为A的友元类别。
与友元功能相似,友元类B中的任何成员函数都可以访问A的私有成员和受保护成员。
让我们通过一个例子更清楚地了解这一点。
我将使用前面的示例,但将添加另一个类" Student",并将其作为" MyClass"的友元类。
#include <iostream>
#include <string>
using namespace std;
class Student;
class MyClass {
private:
int a, b;
public:
MyClass(int a, int b) {
//Constructor
this->a = a;
this->b = b;
}
void set_a(int val);
void set_b(int val);
int get_a() {
return a;
}
int get_b() {
return b;
}
//Declare a friend function of this class
friend void my_fun(MyClass& my_obj, int val, char option);
//Make Student a friend Class of MyClass
friend Student;
};
现在,让我们编写"学生"类:
class Student {
private:
string name;
int marks;
public:
Student(string s_name, int s_marks) {
//Constructor
name = s_name;
marks = s_marks;
}
int get_marks() {
return marks;
}
string get_name() {
return name;
}
void set_marks(Student& stud, int s_marks) {
stud.marks = s_marks;
}
void set_name(Student& stud, string s_name) {
stud.name = s_name;
}
void change_a(MyClass& my_obj, int val) {
//You need to pass the object by reference.
//Otherwise, it will not reflect the changes on
//the original object
my_obj.a = val;
}
void change_b(MyClass& my_obj, int val) {
//You need to pass the object by reference.
//Otherwise, it will not reflect the changes on
//the original object
my_obj.b = val;
}
};
如您所见,我正在使用change_a()和change_b()直接更改MyClass对象的属性!
现在,让我们运行下面的完整代码段。
#include <iostream>
#include <string>
using namespace std;
class Student;
class MyClass {
private:
int a, b;
public:
MyClass(int a, int b) {
//Constructor
this->a = a;
this->b = b;
}
void set_a(int val);
void set_b(int val);
int get_a() {
return a;
}
int get_b() {
return b;
}
//Declare a friend function of this class
friend void my_fun(MyClass& my_obj, int val, char option);
//Make Student a friend Class of MyClass
friend Student;
};
class Student {
private:
string name;
int marks;
public:
Student(string s_name, int s_marks) {
//Constructor
name = s_name;
marks = s_marks;
}
int get_marks() {
return marks;
}
string get_name() {
return name;
}
void set_marks(Student& stud, int s_marks) {
stud.marks = s_marks;
}
void set_name(Student& stud, string s_name) {
stud.name = s_name;
}
void change_a(MyClass& my_obj, int val) {
//You need to pass the object by reference.
//Otherwise, it will not reflect the changes on
//the original object
my_obj.a = val;
}
void change_b(MyClass& my_obj, int val) {
//You need to pass the object by reference.
//Otherwise, it will not reflect the changes on
//the original object
my_obj.b = val;
}
};
void my_fun(MyClass& my_obj, int val, char option) {
//Friend function that sets the private variables
//based on the option
if (option == 'a') {
//Set a
my_obj.a = val;
}
else {
//Set b
my_obj.b = val;
}
}
int main() {
MyClass my_obj(1, 2);
cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
//Friend functions can be accessed from outside the class!
my_fun(my_obj, 20, 'a');
my_fun(my_obj, 40, 'b');
cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
//Class Student objects
Student stud("Amit", 34);
cout << "stud.name = " << stud.get_name() << " and stud.marks = " << stud.get_marks() << endl;
//Change my_obj.a and my_obj.b using the friend class
stud.change_a(my_obj, 100);
stud.change_b(my_obj, 200);
cout << "After using the Friend Class methods,\n";
cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
return 0;
}
输出
my_obj.a = 1 and my_obj.b = 2 my_obj.a = 20 and my_obj.b = 40 stud.name = Amit and stud.marks = 34 After using the Friend Class methods, my_obj.a = 100 and my_obj.b = 200
实际上,"友元"类方法所做的更改确实反映在" my_obj"中。

