了解纯虚函数

时间:2015-06-28 04:53:14

标签: c++ virtual

以下代码编译良好:

struct A
{
    const int a;
    virtual void foo() = 0;
};

struct B : A{ };

void A::foo(){ std::cout << "foo" << std::endl; }

DEMO

结构A是一个摘要,因此我们无法实现它。但是我们可以将它子类化并

struct A
{
    const int a;
    virtual void foo() = 0;
};

struct B : A{ };

void A::foo(){ std::cout << "foo" << std::endl; }

int main(int argc, char ** argv)
{
    B b;
    b.foo(); //error: implement pure-virtual
}

DEMO

仍然无法使用A foo的{​​{1}}实现,我怀疑它永远不会被调用。所以,我不知道应用这样的定义......是的,为虚拟析构函数提供定义很有用,但事实并非如此。

哪里可以使用纯虚拟的定义?

4 个答案:

答案 0 :(得分:3)

您可以明确地调用它。

struct A
{
    const int a;
    virtual void foo() = 0;
};

struct B : A
{
    void foo();
};

void A::foo()
{
    std::cout << "A::foo" << std::endl;
}
void B::foo()
{
    A::foo(); // here
    std::cout << "B::foo" << std::endl;
}

int main(int argc, char ** argv)
{
    B b;
    b.foo(); // prints A::foo followed by B::foo
}

答案 1 :(得分:2)

您可以在B内拨打电话。由于A::foo()是纯虚拟的,B需要定义foo:

struct A {
    virtual void foo() = 0;
};

void A::foo(){ std::cout << "A::foo() ran" << std::endl; }    

struct B : A {
    void foo() {
        A::foo(); // <--
        std::cout << "B::foo() ran" << std::endl;
    }
};

int main(int argc, char ** argv)
{
    B b;
    b.foo();
}

答案 2 :(得分:2)

但你可以(并且必须)实现(如果B是可实例化的)A的void foo()的覆盖。而实现CAN(但绝对不需要)调用BASE实现:

struct B : public A
{
    virtual void foo() {A::foo();}
};

我已经实现了这个场景,我有一个非常简单的“基础”实现,但要求所有叶子ACTIVELY决定通过链接回这个常见的实现来利用这个基础(或不)。

答案 3 :(得分:0)

这是在C ++中实现接口的方法。您强制子类实现要实例化的方法,并且您在自己的代码中以多态方式操作该抽象基类,将特定实现留给您的接口的客户端。

就基类的实现而言,我只能想到两个原因。一,允许他们不必特殊情况下的析构函数。第二,B可以根据A :: foo(),IE,默认实现来定义自己的实现。