从没有虚拟或引用

时间:2015-07-01 16:34:22

标签: c++

考虑代码:

#include <iostream>

class A {
public:
    void g() {std::cout << "Call from A" << std::endl;}
    void f() {g();}
};

class B : public A {
public:
    void g() {std::cout << "Call from B" << std::endl;}
};

int main() {
    B b;
    b.f(); // "Call from A" 
}

如果我将A::g()设为虚拟,则输出“来自B的呼叫”。

当我们希望接口允许多态时,我总是理解“虚拟”很有用,比如说A *a = new B(); a->f(),但是这个例子表明在这种情况下也需要virtual。我对此示例的理解是g()上的A::f调用正式等同于this->g(),这是一个指针。

然而,这不是我真正想要的:在我的真实示例中,我有一个通用模板类A,其中包含一般方法A::simulate(比如A::f),它使用不同的方法(比如说{ {1}}),其中一些被子类覆盖(比如A::g())。我想要的是让方法B以这样的方式将代码编译在A的子类中,就像它已经在子类上定义一样,所以我没有多次相同的逻辑编码。我怎么能这样做?

这是因为我的界面不需要多态,因为用户总是需要编译代码(即它只是标题)。

1 个答案:

答案 0 :(得分:11)

你可以简单地让你的基类为CRTP(正如你所提到的那样,它已经是一个模板化的类):

#include <iostream>

template<class Derived>
class A {
public:
    void g() {std::cout << "Call from A" << std::endl;}
    void f() { static_cast<Derived*>(this)->g();}
            // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Call g() from Derived
};

class B : public A<B> {
public:
    void g() {std::cout << "Call from B" << std::endl;}
};

int main() {
    B b;
    b.f(); // "Call from B" 
}