【问题标题】:base class ambiguous when converting derived class pointer to base class将派生类指针转换为基类时基类不明确
【发布时间】:2016-11-09 06:18:08
【问题描述】:

我正在使用 C++。当我尝试将派生类的指针转换为基类时,编译器会抱怨“基类不明确”。

我做了一些研究,发现了这个问题How can I avoid the Diamond of Death when using multiple inheritance?。还有其他一些类似的问题。

有一个解决办法,就是使用virtual inheritance。但我无法更改类定义,因为它们是编译库。

是否可以在不更改基类定义的情况下进行转换?

一个最小的样本是:

class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};

我想做的是:

D *d = new D;
A *a = (D *)d;  // ambiguous

【问题讨论】:

  • 您是如何设计出这样的设计的?正是因为这个原因,钻石继承是不受欢迎的。
  • 这个问题是一个概念问题。您不只是以某种不透明、神奇的方式“转换指针”。您真正要做的是从更派生的对象中获取基本子对象的地址。一旦您意识到这一点,并且您可能有多个相同类型的基础子对象这一事实,解决方案就会变得清晰。
  • 我正在维护一个古老的项目,无法修改基类。
  • 如果你能提供一个说明问题的最小代码会更好

标签: c++


【解决方案1】:

是否可以在不更改基类定义的情况下进行转换?

是的。您必须选择要通过的直接基类。

class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};

void foo(A&) {}

int main() {
    D d;

    foo(static_cast<B&>(d));
    foo(static_cast<C&>(d));

    return 0;
}

【讨论】:

  • @MartinZhai,很高兴我能帮上忙。觉得应该是个答案。但说真的,看看你是否可以更新基类。您可能会感到惊讶。
  • 那将是一个更好的解决方案,而且这个解决方案现在已经足够了。
【解决方案2】:

我找到了一种方法来进行这种转换,不过有点棘手。

以下代码可以完成这项工作:

A *a = (B *)d;

【讨论】:

  • "(B *)d" 你能解释一下吗?我知道“*B”是什么意思,但这很混乱
  • @imtithal 这是首先将d显式转换为B的指针。然后编译器会将B的指针隐式转换为A的指针(不再模棱两可,因为B只有一个父类)。
猜你喜欢
  • 2013-09-23
  • 1970-01-01
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
  • 2016-12-31
相关资源
最近更新 更多