将ptr转换为派生类的ptr [重复]

Posted

技术标签:

【中文标题】将ptr转换为派生类的ptr [重复]【英文标题】:Casting to a ptr to ptr of derived class [duplicate] 【发布时间】: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;

【问题讨论】:

【参考方案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://***.com/a/2532428/2079934)运行:

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

c 现在指向 Base,而不是 Child

【讨论】:

“Child* 不是 Base* 的派生类” 是空洞的,因为指针根本不是类类型 :) 由于您链接到的问答是该线程被标记为欺骗的完美目标,因此下次您知道此类欺骗目标线程时,请考虑提出(可能的)欺骗目标而不是不必要的在副本中复制副本目标的信息。

以上是关于将ptr转换为派生类的ptr [重复]的主要内容,如果未能解决你的问题,请参考以下文章

声明指向基类和派生类的指针

unique_ptr 到派生类作为函数的参数,该函数将 unique_ptr 带到基类

通过取消引用 boost::shared_ptr 找不到派生类的方法

在dynamic_pointer_cast之后调用派生类的构造函数

为啥我不能返回对使用模板创建的派生类的 unique_ptr 的引用?

将shared_ptr的向量复制到抽象基的派生类中。