【问题标题】:C++ multiple inheritance and mutiple implementation compiles but crashesC++ 多重继承和多重实现编译但崩溃
【发布时间】:2013-12-25 02:18:52
【问题描述】:

我遇到了一种我以前从未见过的奇怪的 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 的对象布局是不同的。但是,为什么动态演员表会起作用?

谁能告诉我有关此 Code Pattern 的更多信息?

非常感谢, 无用的

【问题讨论】:

  • struct AB 不在AB1AB2 的继承层次结构中(即它不是AB1AB2 的父级或子级)。似乎充其量您可以转换为共同的祖先A*B*,但是将层次结构从像这样的“表亲”重新转换似乎不应该是有效的。
  • 你从不检查演员表是否成功——这太懒了。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果x 是指向动态类型不是AB 或其派生类型的对象的指针,dynamic_cast&lt;AB*&gt;(x) 的结果将为0。由于AB 可能会稍后在继承图中的某个位置注入,并且如果具体对象使用多重继承继承它们,则可以使用dynamic_cast 跨层次结构进行强制转换,因此编译器没有理由假设指针不指向可以是 AB 的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 2013-10-22
      相关资源
      最近更新 更多