C ++多重继承和纯函数

时间:2014-04-18 11:36:56

标签: c++ multiple-inheritance pure-virtual

我对多重继承问题感到有些困惑"。考虑以下大量代码:

#include <iostream>

struct iface
{
    virtual void foo () = 0;
    virtual ~iface () {}
};

struct wrapped
{
    virtual void foo ()
    {
        std::cerr << "wrapped\n";
    }
};

struct impl : public wrapped, public iface
{
};

iface* factory ()
{
    return new impl;
}

int main ()
{
    iface *object = factory ();

    object->foo();

    delete object;

    return 0;
}

这是从使用pimpl习语的一些代码中抽象出来的。这个想法是wrapped是一个复杂的类,有各种各样的花里胡哨。 iface仅使wrapped的特定方面可见,factory()函数构建impl类,使用iface实现wrapped。在我的真实代码中,wrapped类来自具有巨大标题树的库,因此我在单独的编译单元中定义impl以避免我的应用程序的其余部分必须将它们拉入。< / p>

无论如何,我粘贴的内容无法编译,并给出以下错误:

$ g++ -o test test.cc
test.cc: In function ‘iface* factory()’:
test.cc:23:16: error: cannot allocate an object of abstract type ‘impl’
     return new impl;
                ^
test.cc:17:8: note:   because the following virtual functions are pure within ‘impl’:
 struct impl : public wrapped, public iface
        ^
test.cc:5:18: note:     virtual void iface::foo()
     virtual void foo () = 0;
                  ^

显然,我可以通过在foo中编写一个转发到impl的{​​{1}}的具体实现来避免错误,但我不明白为什么编译器没有&#39} ; t从wrapped::foo()类中获取实现。

我认为不知怎的&#34; foo&#34;来自wrapped和&#34; foo&#34;来自iface的{​​{1}}在为wrapped进行名称解析(这是正确的词)时最终会有所不同,但我并不理解为什么。

有人能解释一下发生了什么吗?

2 个答案:

答案 0 :(得分:3)

如果一个类的任何虚函数是纯虚函数,则该类是absrtract。 类impl有两个具有相同名称的成员函数

iface::foo

wrapped::foo

类impl的第一个成员函数是纯虚函数,因此该类是抽象的。编译器可能无法创建抽象类的对象。

答案 1 :(得分:1)

impl有两个完全独立的方法,iface::foo,纯粹的,wrapped::foo。没有名称解析 - 虚拟函数调用由名为vtable的结构调度,该结构包含指向实现的指针。对于每个直接祖先,类都有单独的vtable,至少在没有虚拟继承的情况下。来自不同祖先的同义虚函数最终会出现在不同的vtable中;编译器无法“组合”它们。 C ++没有mixins。

  

显然,我可以通过在impl中编写foo的具体实现来避免错误,该实现转发到wrapped :: foo()

更好的是,不要使用双重继承 - 执行类似

的操作
struct impl : public iface
{
    virtual void foo ()
    {
        wr.foo ();
    }
private:
    wrapped wr;
};