c ++虚拟方法没有被调用

时间:2012-05-07 18:39:05

标签: c++ virtual

我在头文件中声明了两个c ++类。基数声明一个虚方法,第二个类重写它。这些实现是在.cpp文件中。

代码相当简单

void DefendProperty::apply(Queue<Defend*>* defendQueue, 
const Tool* toolSource, const Actor* actorSource, const Actor* defender) {
    cout << "BASE" << endl;
}

void DefendPropertyPhysical::apply(Queue<Defend*>* defendQueue, 
Tool* toolSource, const Actor* actorSource, const Actor* defender) {
    cout << "CORRECT" << endl;
    defendQueue->enqueue(new Defend(
        DefendTypePhysical::TYPE, 
        new DamageValuesPhysical(
        getRandomDouble(minDamageReduction, maxDamageReduction))
    ));
}

关键是当我将类实例化为B时,它输出BASE,而不是CORRECT。我不知道此时发生了什么。

这些类存储在没有apply方法的基本ToolProperty类型中。调用它们时,使用dynamic_cast将它们类型转换为DefendProperty类型。

dynamic_cast<DamageProperty*>(node->value)->apply(damageQueue, toolSource, actorSource);

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:3)

派生类中方法的签名与基类中的签名不同。 (一个是const Tool*,另一个是非const Tool*

由于签名不同,派生类的方法不会覆盖基类的方法,而是声明一个新的,不相关的方法。

答案 1 :(得分:1)

您的功能有不同的签名。查看“toolSource”的类型。你的第二个不是第一个的重写,而是过载。

编译器几乎不会警告你的常见错误。我不知道有人会这样做。

顺便说一句,如果您要在指针上使用动态强制转换并且不检查结果,则没有理由使用动态强制转换。

答案 2 :(得分:0)

  1. 确保功能签名相同。 toolSource中的DefendPropertyPhysical不是常量。如果签名不匹配,c ++编译器将不会假设您犯了错误,它只会假设您声明该方法的新重载。 C++11's explicit override对此有所帮助。

  2. 确保标题中的DefendProperty::apply标记为virtual