文章目录
- 一、友元函数
- 二、友元类
- 三、内部类
- 四、小结
一、友元函数
友元函数是定义在类外的普通函数,但是可以访问类的所有成员,包括私有和保护成员。
它不是类的成员函数,但是要在类里声明。
例子:
class A
{// 友元函数可以在类中任何地方声明,不受访问限定符限制friend void print();public:...private:int a;int b;int c;
};// 友元函数是定义在类外的普通函数
// 但是可以访问类的私有和保护成员
void print()
{cout << a << ' ' << b << ' ' << c << endl;
}
注意,一个函数可以是多个类的友元函数,只要在每个类中声明友元函数即可。
二、友元类
如果 A 是 B 的友元类,则在 A 中可以访问 B 的所有成员,包括私有和保护成员。
前提是要在 B 里声明 A 是 B 的友元类。声明方式与友元函数类似,可以在类中任何地方声明,不受访问限定符限制。
例子:
class B
{// 友元类可以在类中任何地方声明,不受访问限定符限制friend class A;public:...private:int x;int y;int z;
};class A
{
public:// 声明了友元类,在 A中就可以访问 B的私有和保护成员void func(B& d){d.x = 1;d.y = 2;...}private:...
};
注意,友元关系是单向的,而且不能传递、不能继承。
单向:比如上面的例子中,A 是 B 的友元类,但是 B 不是 A 的友元类,B 中不能访问 A 的非公有成员,除非也在 A 中声明 B 是 A 的友元类。
不能传递:比如 A 是 B 的友元类,B 是 C 的友元类,但是不能推出 A 是 C 的友元类。
不能继承:to be continued…
三、内部类
在一个类里声明的另一个类,叫作内部类。
内部类可以访问外部类的所有成员,包括私有成员和保护成员。但是外部类不能访问内部类的非公有成员。
例子:
class A
{
public:// B是 A的内部类class B {public:// B中可以访问 A的所有成员void func(A& d) {d.x = 1;d.y = 0;}};
private:int x;int y;
};
事实上,内部类就是外部类的友元类,它们是两个独立的类。
但是创建内部类的对象时,需要这样表示:外部类名::内部类名 对象名
例子:
class OuterClass
{
public:class InnerClass {public:void display() {cout << "Inner Class" << endl;}};
};int main()
{OuterClass::InnerClass innerObj;//创建内部类的对象innerObj.display();return 0;
}
内部类可以在外部类的任意位置声明,但是与友元类声明不同的是,内部类会受访问限定符的限制。
四、小结
友元提供了一种突破封装的方式,有时可以提供便利。
但是友元会增加类与类之间的耦合度,不宜多用。