首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当c++遇到菱形问题时会发生什么

当c++遇到菱形问题时会发生什么
EN

Stack Overflow用户
提问于 2012-10-17 05:27:28
回答 2查看 160关注 0票数 1

来自java背景,我从来没有遇到过菱形问题,在那里多重继承会导致覆盖问题,正如在http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem中详细描述的那样。

但是,如果发生这个问题,c++运行时会抱怨吗?或者是随机调用超类方法的哪个实现?

我读过这篇文章的“缓解”部分,但没有完全理解它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-17 06:23:35

编译器将通过诊断任何歧义来捕获遇到菱形问题的程序。

一种解决方案是消除歧义。在使用显式名称限定引用成员时,可以这样做:

代码语言:javascript
运行
复制
struct B {
    int bar;
};

struct D1 : B {};
struct D2 : B {};

struct E : D1, D2 {};

int main() {
    E e;
    e.D1::bar = 1; // explicitly set D1::bar, not D2::bar.
}

或者,如果您想要访问一个基本子对象,比如:B *b = new E;,那么您想要从D1还是D2访问基本子对象是不明确的。对这些中间类型之一使用显式强制转换可以解决多义性。

代码语言:javascript
运行
复制
B *b = static_cast<D2*>(new E);

还要注意,从B*到E*的向下转换不可能是静态的;编译器不知道指向哪个B,所以它不知道如何静态地调整指针以返回到E。这就需要dynamic_cast。

代码语言:javascript
运行
复制
E *e = new E;
B *b1 = static_cast<D1*>(e);
B *b2 = static_cast<D2*>(e);
assert(b1 != b2);
assert(dynamic_cast<E*>(b1) == dynamic_cast<E*>(b2));
assert(e == dynamic_cast<E*>(b1));

另一种解决方案是使用虚拟继承来避免这个问题,从而避免同一类型的多个基本子对象。

代码语言:javascript
运行
复制
struct B {
    virtual void foo() = 0;
    virtual ~B() = default;
    int bar;
};

struct D1 : virtual B {};
struct D2 : virtual B {};

struct E : D1, D2 {
    virtual void foo() override {
        bar = 1; // no ambiguity because there's only a single B base sub-object
    }
};
票数 2
EN

Stack Overflow用户

发布于 2012-10-17 05:33:17

错误被编译器捕获。http://www.parashift.com/c%2B%2B-faq-lite/mi-diamond.html提供了一个示例

代码语言:javascript
运行
复制
class Base {
public:
protected:
  int data_;
};

class Der1 : public Base {  };

class Der2 : public Base {  };

class Join : public Der1, public Der2 {
public:
  void method()
  {
      data_ = 1; //g++ error: reference to ‘data_’ is ambiguous
  }
};

int main()
{
  Join* j = new Join();
  Base* b = j; //g++ error: ‘Base’ is an ambiguous base of ‘Join’
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12923686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档