将指针转换为派生类的指向指针的指针

5

如果我不指定对Base**的显式转换,为什么会出现编译错误?

当我处理派生类时,我能使用指向指针的指针吗?

class Base { };
class Child : public Base { };

void SomeFunction(Base** ppoObj) {}
void SomeFunction(Base* poObj) {}

int main()
{   
    Child *c = new Child();

    // This passed.
    SomeFunction(c);
    SomeFunction((Base**)&c);

    // CompilationError
    SomeFunction(&c);

    return 0;
}
3个回答

8
虽然您可以将Child*隐式转换为Base*,但是从Child**Base**没有隐式转换,因为它可能会违反类型安全性。请考虑以下情况:
class Base { };
class Child1 : public Base { };
class Child2 : public Base { };

int main() {
    Child1 *c = new Child1();
    Base **cp = &c;  // If this were allowed...
    *cp = new Child2();  // ...then this could happen.  (*cp is a Base*)
}

更多信息请查看C++ FAQ:

正确继承的相关问题


当我使用SomeFunction((Base**)&c)时,我的程序运行良好。在运行时可能会出现什么问题?@Wyzard - Itay Avraham
1
没错,这里没有隐式转换。你的显式转换覆盖了编译器的类型检查 - 就像你可以将Child1 *强制转换为Child2 *一样,即使它们是不相关的类型。只要您只分配与兼容类型的指针(即不要像我在示例中所做的那样),将Child **转换为Base **应该是可以的。 - Wyzard

1

如果我不指定将Base **转换为Child **,为什么会出现编译错误?

因为Child **不能隐式转换为Base **

当我处理派生类时,我可以使用指向指针的指针吗?

如果你的意思是“我可以将Child **分配给Base **类型的变量吗”,那么答案是:不可以。


1

ChildBase的派生类,但Child*不是Base*的派生类。

如果编译器允许指针之间的自动转换,你将会得到以下糟糕的示例(改编自https://dev59.com/aXE85IYBdhLWcg3w8IbK#2532428):

Child *c = new Child;
Base **bb = &c;
*bb = new Base;

c 现在指向一个 Base,而不是一个 Child


“Child*不是Base*的派生类”是真空地成立的,因为指针根本不是类类型 :) - StoryTeller - Unslander Monica
3
由于您提供的问答链接是此主题被标记为重复的完美目标,请在下次知道这样的重复目标线程时,考虑提出(可能的)重复目标,而不是不必要地在重复中复制重复目标的信息。 - dfrib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接