C++ 友元函数
正如我们已经知道的,在面向对象编程语言中,类的成员只能访问该类的数据和函数,而外部函数无法访问该类的数据。可能会出现需要外部函数访问类的私有成员的情况,在这种情况下,友元函数就出现了。
什么是友元函数
友元函数是类的函数,定义在类范围之外,但它有权访问类的所有私有和受保护成员。
友元函数出现在类定义中,但友元函数是成员函数。
友元函数的特点
- 该函数不在被声明为友元的类的作用域内。
- 它不能使用对象来调用,因为它不在该类的作用域内。
- 它可以像普通函数一样被调用,不需要使用对象。
- 它不能直接访问成员名称,必须使用对象名称和点运算符与成员名称结合使用。
- 它可以声明在私有部分或公共部分。
为什么我们需要在C++中使用友元函数
- 在C++中使用友元函数可以直接访问类的私有数据,而不需要使用该类的对象。
- 友元函数也用于执行运算符重载。正如我们已经知道的,函数重载可以进行函数重载,运算符也可以通过运算符重载进行重载。
友元函数的特点
- 使用friend关键字声明友元函数。
- 它不是类的成员,但它是类的友元。
- 由于它不是类的成员,所以它可以像普通函数一样定义。
- 友元函数不直接访问类的数据成员,而是将对象作为参数传递。
- 它是一个普通函数。
- 如果我们想在一个函数中共享多个类的数据,则可以使用友元函数。
友元函数声明的语法。
class class_name
{
friend data_type function_name(argument/s); // syntax of friend function
};
在上述声明中,friend函数前面有关键字friend。这个函数可以像普通的C++函数一样在程序中的任何地方被定义。函数定义不使用关键字friend或作用域解析运算符。
让我们通过一个例子来理解friend函数。
#include
using namespace std;
class Distance
{
private:
int meters;
public:
// constructor
Distance()
{
meters = 0;
}
// definition of display_data() method
void display_data()
{
std::cout << "Meters value : " << meters<
在上面的代码中, Distance 是包含名为 meters 的私有字段的类。 Distance() 是构造方法,它将’meters’的值初始化为0。 display_data() 是一个显示’meters’值的方法。 addvalue() 是Distance类的友元函数,用于修改 ‘meters’ 的值。 在()方法中,d1是Distance类的一个对象。
输出:
友元函数在我们处理两个不同类的对象时也很有用。
让我们通过一个例子来理解。
// Add members of two different classes using friend functions
#include
using namespace std;
// forward declaration of a class
class ClassB;
// declaration of a class
class ClassA {
public:
// constructor ClassA() to initialize num1 to 12
ClassA()
{
num1 =12;
}
private:
int num1; // declaration of integer variable
// friend function declaration
friend int multiply(ClassA, ClassB);
};
class ClassB {
public:
// constructor ClassB() to initialize num2 to 2
ClassB()
{
num2 = 2;
}
private:
int num2; // declaration of integer variable
// friend function declaration
friend int multiply(ClassA, ClassB);
};
// access members of both classes
int multiply(ClassA object1, ClassB object2)
{
return (object1.num1 * object2.num2);
}
int main() {
ClassA object1; // declaration of object of ClassA
ClassB object2; // declaration of object of ClassB
cout << "Result after multiplication of two numbers is : " << multiply(object1, object2);
return 0;
}
在上面的代码中,我们定义了两个类,分别为 ClassA 和 ClassB 。这两个类中都包含了友元函数 multiply() 。友元函数可以访问两个类的数据成员,即 ClassA 和 ClassB 。multiply()函数访问了 ClassA 和 ClassB 的num1和num2。在上面的代码中,我们分别创建了ClassA和ClassB的object1和object2。multiply()函数将num1和num2相乘并返回结果。 从上面的代码中我们可以观察到,在没有事先声明 ClassB 的情况下, ClassA 中的友元函数也使用了 ClassB 。所以,在这种情况下,我们需要提供 ClassB 的前向声明。
输出:
C++中的友元类
我们还可以使用 friend 关键字来创建友元类。
class Class1;
class Class2
{
// Class1 is a friend class of Class2
friend class Class1;
.. .....
}
class Class1
{
....
}
在上述声明中,Class1被声明为Class2的友元类。在Class1中可以访问Class2的所有成员。
让我们通过一个例子来理解。
// C++ program to demonstrate the working of friend class
#include
using namespace std;
// forward declaration
class ClassB;
class ClassA {
private:
int num1;
// friend class declaration
friend class ClassB;
public:
// constructor to initialize numA to 10
ClassA()
{
num1 = 10;
}
};
class ClassB {
private:
int num2;
public:
// constructor to initialize numB to 1
ClassB()
{
num2 = 1;
}
// member function to add num1
// from ClassA and num2 from ClassB
int add() {
ClassA objectA;
return objectA.num1 + num2;
}
};
int main() {
ClassB objectB;
cout << "Sum: " << objectB.add();
return 0;
}
在上面的代码中,我们创建了两个类,分别命名为ClassA和ClassB。由于ClassA被声明为ClassB的友元类,所以ClassA可以访问ClassB的所有数据成员。在ClassB中,我们定义了一个函数add(),它返回num1和num2的和。由于ClassB被声明为ClassA的友元类,所以我们可以在ClassB中创建ClassA的对象。
输出