C++友元函数与友元类
提示
- 友元函数和类:在C++中,友元函数和类提供了一种访问类的私有和受保护成员的机制。友元函数可以是不同类的成员函数,而友元类的所有成员函数都是另一个类的友元。
- 友元函数的声明和使用:友元函数通过在类内使用
friend
关键字声明。它们能够访问类的所有私有和受保护成员,有助于实现两个不同类的对象之间的操作。 - 友元类的特性:当一个类被声明为另一个类的友元时,这个友元类的所有成员函数都可以访问原始类的私有和受保护成员。友元关系是单向的,不是相互的。
数据隐藏是面向对象编程的一个基本概念。它限制了从类外部访问私有成员。
同样,受保护成员只能被派生类访问,从外部无法访问。例如,
class MyClass {
private:
int member1;
}
int main() {
MyClass obj;
// 错误!无法从这里访问私有成员。
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 << "距离: " << addFive(D);
return 0;
}
输出
距离: 5
这里,addFive()
是一个友元函数,可以访问私有和公共数据成员。
尽管这个示例让我们了解了友元函数的概念,但它并没有展示任何有意义的用途。
更有意义的用途是操作两个不同类的对象。这时候友元函数就非常有帮助了。
示例 2:使用友元函数添加两个不同类的成员
// 使用友元函数添加两个不同类的成员
#include <iostream>
using namespace std;
// 前向声明
class ClassB;
class ClassA {
public:
// 构造函数初始化 numA 为 12
ClassA() : numA(12) {}
private:
int numA;
// 友元函数声明
friend int add(ClassA, ClassB);
};
class ClassB {
public:
// 构造函数初始化 numB 为 1
ClassB() : numB(1) {}
private:
int numB;
// 友元函数声明
friend int add(ClassA, ClassB);
};
// 访问两个类的成员
int add(ClassA objectA, ClassB objectB) {
return (objectA.numA + objectB.numB);
}
int main() {
ClassA objectA;
ClassB objectB;
cout << "总和: " << add(objectA, objectB);
return 0;
}
输出
总和: 13
在这个程序中,ClassA
和 ClassB
都将 add()
声明为友元函数。因此,这个函数可以访问两个类的私有数据。
需要注意的一点是,ClassA
中的友元函数使用了 ClassB
。然而,此时我们还没有定义 ClassB
。
// 在 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) {}
// 成员函数添加 numA
// 来自 ClassA 和 numB 来自 ClassB
int add() {
ClassA objectA;
return objectA.numA + numB;
}
};
int main() {
ClassB objectB;
cout << "总和: " << objectB.add();
return 0;
}
输出
总和: 13
这里,ClassB
是 ClassA
的友元类。所以,ClassB
可以访问 classA
的成员。
在 ClassB
中,我们创建了一个 add()
函数,返回 numA 和 numB 的总和。
由于 ClassB
是友元类,我们可以在 ClassB
内部创建 ClassA
的对象。