2016-04-10 15 views
5

私は別のクラスから派生したクラスを持っていますが、派生クラスのインスタンスを保持するためにベースクラスポインタの配列を使用しますが、ポインタの表記で派生クラスに属するメンバーにアクセスすることはできません。単純なコマンドでこれらのメンバーにアクセスすることはできますか?または、基本クラスを書き換えてメンバを定義し、派生クラスでのみ使用する必要がありますか?ベースクラスのポインタから派生クラスのメンバにアクセス

例:あなたは、オブジェクトがによって指さコンパイラに指示しませんでした:私はポインタ表記で派生クラスに属するメンバーにアクセスすることはできません

class A { 
public: 
    int foo; 
}; 

class B : public A { 
public: 
    char bar; 
}; 

class C : public A { 
    int tea; 
}; 

int main() { 
    A * arr[5]; 
    arr[0] = new B; 

    char test = arr[0]->bar; //visual studio highlights this with an error "class A has no member bar" 

    return 0; 
} 
+1

私が知る限り、派生クラスのメンバーには基本クラスのポインタからアクセスできません。とにかく基本クラスがそれを認識しないからです。ただし、基本クラスのメンバーは派生クラス**のメンバーになりますので、派生クラスのポインタから基本クラスのメンバーにアクセスできます。 –

+0

しかし、データは技術的に正しく存在していますか?それを行うためにメモリオフセットを使用できますか? – Stephen

+2

これは仮想メソッドのためのものです。 C++クラスの仮想メソッドについてまだ学習していない場合は、これを実行する絶好の機会です。 –

答えて

6

これは仕様です

ポインタは派生型のポインタです。

必要があり、それは可能あなたがBへのポインタがその100%確信している場合は、static_cast<B*>(arr[0])を実行する場合は、それを行うことができ、私はシンプルなコマンド

でこれらのメンバーにアクセスするためのものですが、解決策をキャスト最後の手段として使用する。代わりに、あなたは、基本クラスのメンバ関数を派生し、派生クラスで実装を提供する必要があります:あなたのコードの場合は

class A { 
public: 
    int foo; 
    virtual char get_bar() = 0; 
}; 

class B : public A { 
    char bar; 
public: 
    char get_bar() { 
     return bar; 
    } 
}; 
+0

私のアルゴリズムの設計方法は、いつポインタが派生クラスを指しているかを知ることができます。これは私が必要とするものに対して完全に機能します。私は動的なキャストを試みたが、私は静的なキャストをすることについては考えなかった、ありがとう。私はこれを答えとしてマークしています。 – Stephen

+0

あなたはすべての間違った理由で答えを受け入れました。仮想関数の使用を真剣に考えてください。 –

+0

この質問は1つのプログラムのためのもので、そのほとんどはすでに書かれています。私はこの具体的な答えを迅速に解決する必要がありました。将来、私は間違いなく仮想関数を使って仕事を終わらせます。 – Stephen

0

、派生クラスのあなたのメンバーはプライベートです。したがって、基本クラスからアクセスすることはできません。 アクセスする場合は、派生クラスのメンバーを「public」に変更する必要があります。 あなたはこのようなあなたのコードを修正する必要がありますについてtype-casting読む

class B : public A { 
public: 
    char bar; 
}; 

int main() { 
A * arr[5]; 
arr[0] = new B; 

char test = static_cast <B *>(arr[0])->bar; //visual studio highlights this with an error "class A has no member bar" 
return 0; 

}

1

、それは言語の非常に基本的かつ重要な側面です。つまり、常にポインタから派生したポインタにキャストすることができます。次に、固有のパブリックメンバーを参照してください。

A * arr[5]; 
arr[0] = new B; 

char test = static_cast<B*>(arr[0])->bar; 

しかし、上記の最後の行は、そのA*が本当にB型のオブジェクトを指していない場合でも、有効なステートメントです。 Cオブジェクトでこれを試すと、コンパイルされ、実行時に未定義の動作が発生します。

しかし、通常は、彼が指し示すオブジェクトの種類を特定できないときは、プログラムのより良い設計が最初からそれを妨げている可能性があることに言及する必要があります。共通の主張は、一般的にタイプキャスティングに当てはまると言います。

P.S.あなたのコードでは、barclass Bのプライベートメンバーです(間違いなく、classのメンバーはデフォルトでプライベートです)ので、class Bの実装以外ではアクセスできません。

+0

キャスティングは仕事のための適切なツールではなく、特定の言語よりも重要なオブジェクト指向プログラミングのパラダイムなら、基本的な側面ではありません。不十分なオブジェクト指向設計をカバーするために鋳物を使用しないでください。 –

+0

私はこれが議論の余地があると信じています。そして私の理解のために、この質問はOODに関するものではありませんでした。それは技術的な質問であり、タイプキャスティングは、それが形成された方法での質問のための直接的な答えです。トピックを変更しない「仕事のための適切なツール」が分かっている場合は、してください。 –

+0

「これは議論の余地があると思う」私はしません。 "それは技術的な質問だった"。技術的には正しいわけではありませんが、危険な答えではなく、指導を必要とする、何者かによる質問でした。 –

関連する問題