2011-01-05 24 views
2

私はコンパイルすべきではないと思ういくつかのコードを書いています。印刷基本クラスのオブジェクトの派生クラスの呼び出しメソッド

class B {};  

class D: public B 
{ 
public: 
    void bar() { printf("%d\n", m_i); } 
private: 
    int m_i; 
}; 

int main() 
{ 
    B b; 
    D* d = static_cast<D*>(&b); 
    d->bar(); 
    return 0; 
} 

値は明らかに迷惑メールであるが、これもコンパイルする必要があります。私は、次のように基底クラスのオブジェクトためにはstatic_cast-EDポインタに派生クラスのメソッドを呼び出すのですか? gccどうすればそのことができますか?

+3

なぜコンパイルしないのですか?あなたはBをDとしてキャストしています。すべてのコンパイラが知っているので、D – Falmarri

+0

の操作をしています.C++コードでprintfを使わないでください。 – BatchyX

+1

@BatchyX: 'printf'は危険なほど安全ではないかもしれませんが、' cout'や友人よりもかなり速いです。 – Puppy

答えて

1

gccは、本当に価値のない少数のケースを除いて、間違っていることを保証することはできません。 static_castを使用すると、あなたが行っていることを知っていることをコンパイラーに約束します。

ここには2種類のキャストがあります。 static_castは、ベースへのポインタが派生したポインタであることをコンパイラに伝えています。 dynamic_castこれは、ベースへのポインタが実際に派生するポインタであるかどうかをコンパイラに確認するように要求しています。 static_castを使用したので、コンパイラはシャットダウンして、あなたが言ったようにしました。

編集:Johnは、継承階層に仮想関数がないことを正確に指摘しました。これはC++から解雇されるべきであり、dynamic_castは仮想関数に対してのみ有効です。

+0

型が多型ではないため、このpartucularのケースでは 'dynamic_cast'は機能しません。 –

+0

@ジョン:良い点。なぜ人々は継承と仮想機能を伴わないコードの投稿を続けていますか? – Puppy

+0

とった。ばかげた質問。そして、実行時には、変数m_iがオブジェクトをクラスDに持っていたはずのメモリ内の場所の内容を出力するでしょう。 – 341008

0

static_cast <を使用すると、コンパイラに「私は何をしているのか、B *は実際にD *であり、私の言うことをやっているだけだ」と言った。

+0

正確ではありません。 'static_cast'は、2つの型が関連していない限り、コンパイルされません。おそらくあなたは 'reinterpret_cast'を考えているでしょう。 –

+0

@John Dibling:特定のコンパイル時のチェックでは、static_cast <>を使用してコンパイラに'私はあなたよりよく知っています 'と伝えています。その結果、あなたは正しくそれを正しく行うことができます。 –

+0

@ジョンディブリング:私は別段のことを言ったのですか? –

関連する問題