C++ 友元函数和友元类
在本教程中,我们将借助示例学习在 C++ 中创建友元函数和友元类。
数据隐藏是面向对象编程的一个基本概念。它限制了来自类外部的私有成员的访问。
同样,受保护的成员只能由派生类访问,而不能从外部访问。例如,
class MyClass {
private:
int member1;
}
int main() {
MyClass obj;
// Error! Cannot access private members from here.
obj.member1 = 5;
}
然而,C++ 中有一个叫做友元函数的特性,它打破了这个规则,允许我们从类外部访问成员函数。
同样,还有一个友元类,我们将在本教程后面学习。
C++中的友元函数
一个友元函数可以访问私有和受保护类的数据。我们在类的主体内使用 friend
关键字声明一个友元函数。
class className {
... .. ...
friend returnType functionName(arguments);
... .. ...
}
示例 1:友元函数的工作
下面的 C++ 程序演示了友元函数的工作方式。
#include <iostream>
using namespace std;
class Distance {
private:
int meter;
// 友元函数
friend int addFive(Distance);
public:
Distance() : meter(0) {}
};
// 友元函数定义
int addFive(Distance d) {
// 访问对象的私有属性
d.meter += 5;
return d.meter;
}
int main() {
Distance D;
cout << "Distance: " << addFive(D);
return 0;
}
输出
Distance: 5
这 addFive()
是一个可以访问私有和公共数据成员的友元函数。
尽管这个例子让我们对友元函数的概念有了一个概念,但它并没有显示出任何有意义的用途。
更有意义的用途是对两个不同类的对象进行操作。这时候友元功能就非常有用了。
示例 2:添加两个不同类的成员
该程序演示友元函数对了两个类的对象的操作。
#include <iostream>
using namespace std;
// 提前声明
class ClassB;
class ClassA {
public:
ClassA() : numA(12) {}
private:
int numA;
// 友元函数声明
friend int add(ClassA, ClassB);
};
class ClassB {
public:
ClassB() : numB(1) {}
private:
int numB;
// 友元函数声明
friend int add(ClassA, ClassB);
};
// access members of both classes
int add(ClassA objectA, ClassB objectB) {
return (objectA.numA + objectB.numB);
}
int main() {
ClassA objectA;
ClassB objectB;
cout << "Sum: " << add(objectA, objectB);
return 0;
}
输出
Sum: 13
在这个程序中, ClassA
和 ClassB
都声明了 add()
为友元函数。因此,该函数可以访问两个类的私有数据。
这里要注意的一件事是 ClassA
里面的友元函数使用 ClassB
, 但是,我们目前还没有定义 ClassB
。
// inside classA
friend int add(ClassA, ClassB);
为此,我们需要在我们的程序中提前声明 ClassB
。
// 提前声明
class ClassB;
C++ 中的友元类
我们还可以在 C++ 中使用 friend
关键字声明友元类。例如,
class ClassB;
class ClassA {
// ClassB 是 ClassA 的友元类
friend class ClassB;
... .. ...
}
class ClassB {
... .. ...
}
当一个类被声明为友元类时,友元类的所有成员函数都成为友元函数。
由于 ClassB
是友元类,我们可以从 ClassB
内部访问 ClassA
的所有成员。
但是,我们无法从 ClassA
内部访问 ClassB
的成员。这是因为 C++ 中的友元关系只被授予,而不是被接受。
示例 3:C++ 友元类
此程序演示了 C++ 友元类的工作方式。
#include <iostream>
using namespace std;
// 提前声明
class ClassB;
class ClassA {
private:
int numA;
// 声明友元类
friend class ClassB;
public:
// 构造函数,初始化 numA 为 12
ClassA() : numA(12) {}
};
class ClassB {
private:
int numB;
public:
// 构造函数,初始化 numB 为 1
ClassB() : numB(1) {}
int add() {
ClassA objectA;
return objectA.numA + numB;
}
};
int main() {
ClassB objectB;
cout << "Sum: " << objectB.add();
return 0;
}
输出
Sum: 13
这里, ClassB
是 ClassA
的友元类。因此, ClassB
可以访问 classA
.
在 ClassB
中,我们创建了一个函数 add()
,该函数返回 numA
与 numB
的和.
由于 ClassB
是友元类,我们可以在 ClassB
创建 ClassA
的对象.