今天在做 C++ Primer Plus 第十三章课后题时,发现了一个有趣的现象。
题目要求定义一个抽象基类,并派生出三个子类。通过声明基类指针数组的方法,动态的决定每个指针指向的对象。
在基类和派生类中都定义了一个友元函数 ostream & operator<<(ostream & os, const class_ &)。
原意是动态实例化不同的对象以后,使用循环分别调用对象各自的<<重载运算符,实现打印自身成员变量的目的。
但是运行时发现无论是什么对象,打印出来的只有基类的数据,自身的数据不会打印。
经过调试以后发现:
1.友元函数本身不属于类,也不能被继承,只能通过运算符对应的参数类型来决定调用哪个友元函数
2.基类指针可以指向派生类对象,但是将基类指针解引用以后,本身还是作为一个基类对象来看的
基于以上两点,无论指针指向的对象是基类还是派生类,解引用以后都是以基类对象存在的(即使这个基类是抽象基类)。这也解释了为什么每次都只调用基类的友元函数。
同时也发现了一个实例化抽象类的方法,将该类指针指向派生类,再解引用,就可以作为该类的对象使用了,同时也不能访问派生类的数据。