C ++多重继承和多个实现编译但崩溃

时间:2013-12-07 19:47:26

标签: c++ design-patterns multiple-inheritance

我遇到过一种我以前从未见过的奇怪的C ++继承模式:

有两个接口A和B.每个接口有两个不同的实现,分别称为A1和A2,B1和B2。此外,接口AB继承自接口A和B,并且有两个派生类AB1和AB2使用实现A1和B1,A2和B2。

问题是:

如果我有一个AB指针,有没有办法分配AB1或AB2的指针?以下代码演示了此问题。它至少可以用g ++ 4.6或更高版本编译,但它会产生一个seg-fault。如果我使用动态强制转换运算符,则编译器接受从AB1 *到AB *的赋值。

#include <iostream>

// first interface and implementations

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

struct A1 : public A
{
        void a() { std::cout << "A1\n"; };
};

struct A2 : public A
{
        void a() { std::cout << "A2\n"; }
};

// second interface and implementations

struct B
{
     virtual void b() = 0;
};

struct B2 : public B
{
    void b() { std::cout << "B2\n"; }
};

// combining interfaces and implementations

struct AB : public A, public B
{};

struct B1 : public B
{
        void b() { std::cout << "B1\n"; }
};


struct AB1 : public A1, public B1
{};

struct AB2 : public A2, public B2
{};

int main()
{
    AB1* ab1 = new AB1();
    ab1->a();
    ab1->b();  

    AB2* ab2 = new AB2();
    ab2->a();
    ab2->b();

    // this code compiles but doesnt work
    AB* ab;

    ab = dynamic_cast<AB*>(ab1);
    ab->a();
    ab->b();

    ab = dynamic_cast<AB*>(ab2);
    ab->a();
    ab->b();

    return 0;
}

我最好的猜测是AB1,AB2和AB的对象布局不同。但是,为什么动态演员有效?

有人能指出我有关此代码模式的更多信息吗?

非常感谢, schluchtenbummler

2 个答案:

答案 0 :(得分:2)

ab1ab2都不能投放到AB。如果无法执行强制转换,dynamic_cast将返回NULL(如果使用C ++ 11,则返回nullp)。在尝试访问ab之前,您应检查nullptr。你在问题中说“动态演员为什么会起作用?”......答案是,它不起作用,但你没有检查返回值,看是否是这种情况。

答案 1 :(得分:0)

如果dynamic_cast<AB*>(x)是指向动态类型不是0的对象或其派生类型的指针,x的结果将为AB。由于AB可能会在继承图中稍后注入,dynamic_cast可用于跨层次结构转换,如果具体对象使用多重继承继承它们,编译器没有理由认为pounters'' t指向一个可能是AB的对象。