2016-08-17 97 views
5

如果我没有指定显式转换到Base **,为什么会出现编译错误?铸造到派生类ptr到ptr

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

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; 
} 

回答

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*) 
} 

More information in the C++ FAQ

+0

当我使用SomeFunction((Base **)&c)时,我的程序运行良好。 运行时可能会出现哪些问题? @Wyzard –

+1

对,没有*隐式*演员。你的显式强制覆盖了编译器的类型检查 - 就像你可以将一个Child1 *转换为一个Child2 *一样,即使它们是不相关的类型。将'Child **'强制转换为'Base **'应该可以,只要你只指定兼容类型的指针(即不要做我在这个例子中做的)。 – Wyzard

1

为什么我得到一个编译错误,如果我不指定铸造Base**

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

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

如果你的意思是“我能分配到Child**Base**类型的变量”,那么答案是:不,你不能。

1

Child是一个派生类的Base,但Child*不是派生类的Base*

如果编译器确实让你的指针到指针自动转换,你会得到下面的坏榜样(改编自https://stackoverflow.com/a/2532428/2079934)运行:

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

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

+0

*“Child \ *不是基类派生类”*是真实的,因为指针根本不是类类型:) – StoryTeller

+3

由于您链接到的问答是此线程被标记为重复的完美目标考虑下一次你知道这样的目标线程来提出一个(可能的)目标目标而不是不必要的重复目标的目标信息。 – dfri

相关问题