在C++中定义类时,可以通过三个访问说明符(access specifier)来指定其成员的访问权限。
1 访问说明符
这三个访问说明符分别是public、private和protected。其中,public表示该成员可以被所有的人访问;private则与public刚好相反,它表示该成员只能被类内的成员函数访问;而protected表示该成员只能被类内函数和该类的派生类对象访问。
2 友元
在“1访问说明符”中提到,类的private和protected成员不能被外部函数访问。如果外部函数确实需要访问这些成员,则可以将外部函数声明为该类的友元。
2.1 声明类的友元函数
通过关键字friend来声明类的友元函数。例如
class X{
protected:
int i;
friend void g(X* x, int i)
};
以上代码将类外函数g()声明成了类X的友元函数。
2.2 声明及定义友元函数
在“2.1声明类的友元函数”中只是将函数g()声明为类X的友元,并没有对g()进行声明和定义。接下来,在类X定义的外部,对g()进行声明及定义。
void g(X *x, int i)
{
x->i = i;
}
从以上代码中可以看到,在g()中可以访问X的private成员i了。
从以上分析可知,友元声明只能出现在类定义的内部,但在类内出现的具体位置不限。友元不是类的成员,也不受类访问说明符的约束。为了使友元对类用户可见,通常把友元的声明与类本身放置在同一个文件中。
3 友元与继承
3.1 继承
通过继承我们能够定义这样的类,它们对类型之间的关系建模,共享公用的东西,仅仅特化本质上不同的东西。派生类能够继承基类定义的成员,还可以定义更多的成员。
3.2 派生类的友元
在“3.1继承”中提到,派生类可以继承基类的成员,但是派生类不能继承基类的友元。即基类的友元在访问派生类成员时不具有特殊性,而派生类的友元也不能随意访问基类的成员。
class X_Base{
protected:
int i;
private:
int k;
};
class X_Derive:public X_Base{
friend void g(X_Derive* x, int i)
protected int j;
};
此时,在g()中可以通过X_Derive类的指针x访问X_Base的protected成员变量i和X_Derive的protected成员变量j,而不能访问X_Base的private成员变量k。