将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】:Child
是Base
的派生类,但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之后调用派生类的构造函数