首页 理论教育C++友元类的用法和限制

C++友元类的用法和限制

【摘要】:若B类为A类的友元类,则B类的所有成员函数都是A类的友元函数,都可以访问A类的私有和保护成员。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。在较为复杂的问题中,实现不同类之间的数据共享,友元类的使用也是很必要的选择。友元关系是不能继承的。图3.1链式栈解:先声明节点类Node,其中又将栈类Stack作为Node类的友元类。

与友元函数一样,类也可以声明为另一个类的友元,这时成为友元类。若B类为A类的友元类,则B类的所有成员函数都是A类的友元函数,都可以访问A类的私有和保护成员。友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。

当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:

一般的语法格式如下:

通过友元类声明,友元类的成员函数可以通过对象名直接访问到隐藏的数据,达到高效协调工作的目的。在较为复杂的问题中,实现不同类之间的数据共享,友元类的使用也是很必要的选择。

关于友元类,还需要注意以下几点:

(1)友元关系是不能传递的,B类是A类的友元,C类是B类的友元,C类和A类之间,如果没有声明,就没有任何友元关系,不能进行数据共享。

(2)友元关系是单向的,如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数不能访问B类的私有、保护数据。

(3)友元关系是不能继承的。例如:函数f()是类A的友元,类A派生出类B,函数f()并不是类B的友元,除非在类B中做了特殊说明(有关继承的概念将在第6章介绍)。

【例3.15】分析以下程序的执行结果。

解:上述程序中,将类B说明为类A的友元类,因此类B的成员函数可以访问类A的私有数据。程序的执行结果如下:

n=5(www.chuimin.cn)

但是,尽管类B中的成员函数display是类A的友元函数,但不能直接调用display(a),这样会出现以下编译错误:

error C2065:'display':undeclared identifier(display为未说明的标识符)

【例3.16】编写一个程序,实现栈的压入(进栈)和弹出(出栈)。其中有两个类:一个是节点类Node,它包含节点值data和指向下一个节点的指针next;另一个类是栈类Stack,它包含栈的头指针top。链式栈如图3.1所示。

图3.1 链式栈

解:先声明节点类Node,其中又将栈类Stack作为Node类的友元类。由于Node和Stack相互引用,故其中的一个类必须先作不完整声明即前向引用声明,在程序开头,使用“class Stack;”语句对类Stack进行前向引用声明。

栈类Stack作为节点类Node的友元类,因此Stack类中的所有成员函数都可以访问Node类对象的私有成员,从中看到,Stack类的push和pop成员函数都对Node类的私有成员data和next进行了操作。

对于空栈,其top成员为NULL,进栈时,先建立一个Node对象*p,将其作为栈顶节点,top指向它;出栈时,后移top并删除原栈顶节点。完整的程序如下:

程序的执行结果如下:

出栈次序:4 3 2 1