指向基类某个成员的指针可以转换成指向派生类相应成员指针。然而,反过来却不行。这条规则叫做“指向成员的指针的不可逆性”。下面我将解释这个不可逆特性以及隐藏于其后的基本原理。
不可逆性例子
考虑以下两个类:
struct Base
{
virtual void func();
};
struct Derived : Base
{
void func();
};
指向类 Base 的一个成员的指针不能引用类 Derived 的相应成员:
typedef void (Base::*PMF)();
PMF pmf1=&Derived::func; //error
PMF pmf2=&Base::func; //ok
然而,如果定义一个指向类 Derived 的一个成员的指针,那么可以隐式地将其转成指向类 Base 相应成员的指针:
typedef void
(Derived::*PMF)();
PMF pmf1=&Derived::func; //fine
PMF pmf2=&Base::func; //also fine
基本原理
这个不可逆性规则看上去有违直觉。在处理一般的指针和引用时,可以隐式地将一个指向派生类的指针转成一个指向其基类的指针,但是相反却不行:
Base * p =
new Derived; //ok
Derived *p = new Base; //error, can't convert
//'Derived
*' to 'Base *'
然而,在指向成员的指针方面,情况恰恰相反。这是很有必要的,因为一个派生类具有它所继承的基类的所有成员;因此,任何指向基类一个成员的指针都可以映射到派生类相应的成员上。相反行不通,因为派生类可能具有更多基类中不存在的成员。