2013-04-21 12 views
6

このコードは、実行時に適切なメッセージをコンソールに出力することを拒否します。参照の代わりにポインタを使用すると動作するようです( - の代わりに - >)。私はOOPに新しいので、あなたがこれをばかげて見つけたら私を許してください。基本クラスへの参照を通じて仮想関数を呼び出す

#include <iostream> 

using namespace std; 

class instrument { 
public: 
    virtual void play(){} 
}; 

class drum : public instrument { 
public: 
    void play(){ 
     cout << "dum, dum" << endl; 
    } 
}; 

class piano : public instrument { 
public: 
    void play(){ 
     cout << "pling" << endl; 
    } 
}; 

int main(){ 
    instrument i; 
    piano p; 
    drum d; 

    instrument &pi = i; 
    pi.play(); // - 

    pi = p; 
    pi.play(); // pling 

    pi = d; 
    pi.play(); // dum, dum 
} 
+9

参照を初期化時にバインドしたオブジェクトから参照を変更することはできません。今すぐあなたの発射割り当て演算子(およびプロセスでの[オブジェクトのスライス](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c/274634#274634)のトリガー)。 – WhozCraig

+4

これを答えてください、そうでしょうか? – jrok

+0

問題がありますが、基本クラスに仮想デストラクタを作成する必要があります。 –

答えて

15
instrument &pi = i; 
ここ

あなたがpiを作るには、instrumentオブジェクトiを参照してください。

pi = p; 

ここでは、piによって参照されるオブジェクトにpianoオブジェクトpを割り当てています。参照piは、pianoオブジェクトに戻されません。以前と同じinstrumentオブジェクトを参照しています。暗黙的に生成されたデフォルトの代入演算子を使用して異なる内容が割り当てられているだけです。 (この場合、代入は効果がありませんが、派生型を基本型に割り当てると、通常はオブジェクトがスライスされます)。pi.play()を呼び出すと、参照は引き続きinstrumentオブジェクトを参照し、instrument::playが実行されます。

ポイントは、別のタイプの別のオブジェクトを指すポインタを得ることができますが、参照で同じことをすることはできません。常に同じオブジェクトを指します。

instrument &pi = i; 
pi.play(); // - 

instrument &pp = p; 
pp.play(); // pling 

instrument &pd = d; 
pd.play(); // dum, dum 
+1

ポインタはもう少しです汎用性と柔軟性は参考文献よりも、そうではありませんか? – Venom

+0

@Venom no。どちらもその用途を持っています –

+1

@Venom生の機能性だけを考えれば、より柔軟性があります。しかし、その柔軟性を常に望むわけではありません。実際、それは問題につながるかもしれません。ジョブの適切なタイプを選択します。 –

関連する問題