该做法的意义何在,姑且不论。今天我们主要关注该功能的实现,至少在实现的思路上是对面向对象思想的一次深入理解。
首先一点,父类引用是无法调用子类独有的方法(不仅无法访问,而且是不可见的),结论是显然的,不然该方法就不作为子类所独有了,不然子类就没有任何的独特之处了(隐私空间),也就丧失了子类存在的意义。
// C++
class Base
{};
class Derived :public Base
{
public:
void foo() {}
};
int main(int, char**)
{
Base* pBase = new Derived;
pBase->foo();
// class “Base” 没有成员 “foo”
return 0;
}
解决方案是,在父类中声明一个虚函数用以向下类型转换,在父类中给出其接口实现(否则会出现链接错误),在子类中自然给出其真正实现。
class Derived;
// 前置声明
class Base
{
public:
virtual Derived& downcast()
{ return *(Derived* )NULL; }
virtual const Derived& downcast() const
{ return *(Derived* )NULL; }
};
class Derived :public Base
{
public:
Derived& downcast()
{ return *this;}
const Derived& downcast() const
{ return *this;}
void foo(){}
};
注意,因为在父类Base
要用到子类Derived
类的声明,我们需要在父类的定义之前,对子类进行前置声明(forward declaration)。
int main(int, char**)
{
Base* pBase = new Derived;
pBase->downcast().foo();
// 通过
return 0;
}