【问题标题】:Virtual Method calling another virtual method in a templatized class虚拟方法调用模板化类中的另一个虚拟方法
【发布时间】:2013-12-11 01:23:52
【问题描述】:

我一直在阅读有关此主题的不同问题,但无法找到一个完全回答我正在寻找的问题的问题。这是我拥有的代码模式:

class Base {
public:
    virtual void foo(int) const {...}
}

template <class T>
class TmplClass : public Base {
public:
    virtual void foo(int i) const { foo(T(i)); }
    virtual void foo(T& param) const {
        printf("Template::Foo\n");
        bar(param);
    }
    virtual void bar(T&) const {
        printf("Template::Bar\n");
    }
}

class Derived : public TmplClass<SomeConcreteType> {
public:
    void bar(SomeConcreteType&) {
        printf("Derived::Bar\n");
    }
}

int main() {
    Derived d;
    Base* b = &d;
    b->foo(1);
}

执行时我得到:

Template::Foo
Template::Bar

为什么调用 bar 的运行时调度不起作用?如果我在 Derived 中重载 foo 那么它确实调用了 foo 的派生版本,为什么它不能为 bar 做动态调度?

因为我正在使用现有代码,所以我不希望在这里更改类的基本结构。我希望能找到一种方法来使通话正常工作,或者了解为什么不能正常通话。根据阅读此处的其他问题,我尝试了很多不同的方法,但都无济于事。

【问题讨论】:

  • Base 在哪里是 Derived 的祖先?
  • 这看起来不像一个工作示例。 void foo(void) 方法不存在,Base 不是任何东西的祖先类。请提供工作代码。
  • 它不起作用,因为此代码无法编译。 This similar program 编译并运行正常。
  • 抱歉,TmplClass 缺少“:public Base”。而且,原来模板问题是一个红鲱鱼。在实际代码中,我的 Derived::Bar 定义没有像 TmplClass::Bar 一样标记为 const where,所以我实际上并没有覆盖该方法。

标签: c++ templates virtual-functions class-template


【解决方案1】:

原来这不是模板问题。代码的问题在于 Derived::bar 方法没有被标记为 const,而 TmplClass::bar 方法被标记为 const。所以,目的是提供一个覆盖,但实际上 Derived::bar 是一个完全不同的方法,具有不同的签名,所以这就是它给出意外行为的原因。一旦从 TmplClass::bar 中删除 const 或将其添加到 Derived::bar ,则签名匹配并收到预期的输出:

Template::Foo
Derived::Bar

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2016-09-28
    • 2011-12-19
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多