在大多数情况下,您只需正常调用虚方法,并让多态根据需要调用最派生的实现。作者试图解释的是,也可以不经过多态直接调用虚方法的具体实现。
假设一个类派生自再次Fibonacci
覆盖gen_elems()
,但您不想调用该覆盖,您想调用Fibonacci
覆盖。通过在编译时将num_sequence
指针转换为Fibonacci
指针(或后代指针),它允许编译器访问Fiboncci
vtable,因此它可以发出代码以直接调用Fibonacci::gen_elems()
(如果在运行时指向的对象实际上不是Fibanocci
或后代,您可能会崩溃/损坏您的应用程序。这无法在编译时验证)。
例如:
class num_sequence
{
public:
virtual void gen_elems(int value)
{
std::cout << "num_sequence" << std::endl;
}
};
class Fibonacci : public num_sequence
{
public:
void gen_elems(int value)
{
std::cout << "Fibonacci" << std::endl;
}
};
class SomethingElse : public Fibonacci
{
public:
void gen_elems(int value)
{
std::cout << "SomethingElse" << std::endl;
}
};
.
num_sequence ns;
Fibonacci fib;
SomethingElse se;
num_sequence *ps;
ps = &ns;
ps->gen_elems(64); // displays "num_sequence"
ps = &fib;
ps->gen_elems(64); // displays "Fibonacci"
ps = &se;
ps->gen_elems(64); // displays "SomethingElse"
ps->Fiboacci::gen_elems(64); // compiler error!
static_cast<Fibonacci*>(ps)->Fibonacci::gen_elems(64); // displays "Fibonacci"
static_cast<SomethingElse*>(ps)->Fibonacci::gen_elems(64); // displays "Fibonacci"
Fibonacci *pfib = dynamic_cast<Fibonacci*>(ps);
if (pfib != NULL)
{
pfib->gen_elems(64); // displays "SomethingElse"
pfib->Fibonacci::gen_elems(64); // displays "Fibonacci"
}