2016-08-17 4 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

あなたが暗黙的にBase*Child*をキャストすることができますが、型の安全性に違反するために使用される可能性があるため、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**に変換されないためです。

派生クラスを扱うときにポインタへのポインタを使用できますか?

ことにより、あなたは「私はBase**型の変数にChild**を割り当てることができます」を意味するならば、答えは:いいえ、あなたがすることはできません。

1

ChildBaseの派生クラスですが、Child*Base*の派生クラスではありません。

コンパイラはあなたへのポインタのポインタの自動変換を許可しなかった場合は、(https://stackoverflow.com/a/2532428/2079934から適応)以下の悪い例の実行になるだろう:

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

c今しないように、BaseにポイントをChild

+0

* "Child \ *はBaseの派生クラスではありません\ *" *ポインタはクラス型ではないため、空であることを意味します:) – StoryTeller

+3

あなたがリンクしているQ&Aはこのスレッドがdupe次回は、そのような標的標的のスレッドが、標的標的の情報を複製に不要に複製するのではなく、(可能な)標的を提示することを知ったときに検討してください。 – dfri

関連する問題