【问题标题】:Casting to a ptr to ptr of derived class [duplicate]将ptr转换为派生类的ptr [重复]
【发布时间】:2016-08-17 13:41:30
【问题描述】:

如果我没有指定对 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;
}

【问题讨论】:

    标签: c++ pointers inheritance casting


    【解决方案1】:

    虽然您可以将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*)
    }
    

    More information in the C++ FAQ

    【讨论】:

    • 当我使用 SomeFunction((Base**)&c) 时,我的程序运行良好。运行时可能会出现什么问题? @Wyzard
    • 对,只是没有 implicit 演员表。您的显式转换会覆盖编译器的类型检查——就像您可以将Child1* 转换为Child2*,即使它们是不相关的类型。将 Child** 转换为 Base** 应该没问题,只要您只分配指向兼容类型的指针(即不要做我在示例中所做的)。
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      如果编译器确实允许您自动转换指针到指针,您会得到以下错误示例(改编自 https://stackoverflow.com/a/2532428/2079934)运行:

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

      c 现在指向 Base,而不是 Child

      【讨论】:

      • “Child* 不是 Base* 的派生类” 是空洞的,因为指针根本不是类类型 :)
      • 由于您链接到的问答是该线程被标记为欺骗的完美目标,因此下次您知道此类欺骗目标线程时,请考虑提出(可能的)欺骗目标而不是不必要的在副本中复制副本目标的信息。
      猜你喜欢
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      相关资源
      最近更新 更多