2012-04-05 8 views
3

クラスDVDはクラスMediaを継承し、基本クラスよりも1つ多くの変数を持ちます。オーバーロード関数を(抽象ではない)基本クラスから呼び出す方法は?

私はポインタを宣言:

Media* ptr = new DVD(...); 

私はDVDの内容をプリントアウトしたいので、期待通りに次のコードは動作します:

ptr->print(cout); 

しかし、唯一のオーバーロードされた< <演算子を使用して基本クラスのprint()関数を呼び出します。

cout << *ptr << endl; 

それで、ディレクターの名前ではなく、IDだけを印刷します。

cout << ptr << endl; 

が動作するはずですが、どういうわけか、私のようにcout << *ptr << endl;作品を作るための方法を見つける必要があります。この問題を解決するための

一つの方法は、そう、それはポインタを受け入れるようにする過負荷< <オペレータビットを変更することです期待される。

アドバイスはありますか?

ostream演算子のオーバーロードでそのインスタンスを呼び出す必要があるため、基本クラスのポインタが派生クラスのオーバーロード関数を呼び出せないため、基本クラス(メディア)抽象クラスを作成できませんクラスを指しています。

コード:

#include <iostream> 
using namespace std; 

class Media{ 
    private: 
     int id; 
    public: 
     Media(int _id) : id(_id) {} 
     virtual ~Media(); 
     virtual void print(ostream &out); 
     friend ostream& operator << (ostream& out, Media aMedia); 
}; 
Media::~Media(){} 

class DVD : public Media { 
    private: 
     string director; 
    public: 
     DVD(int _id, string _director = "unknown") : Media(_id), director(_director) {} 
     ~DVD(); 
     void print(ostream &out); 
}; 
DVD::~DVD(){} 

void Media::print(ostream& out){ 
    out << "ID " << id; 
} 
void DVD::print(ostream& out){ 
    out << "DVD: "; 
    Media::print(out); 
    out << " Directed by " << director; 
} 
ostream& operator << (ostream& out, Media aMedia){ 
    aMedia.print(out); 
    return out; 
} 

int main() { 
    Media *ptr = new DVD(352, "Stephen Spielberg"); 
    ptr->print(cout); // Prints out: "DVD: ID 352 Directed by Stephen Spielberg". Correct! 
    cout << endl; 
    cout << *ptr << endl; //Prints out: "ID 352" Incorrect! 
} 

答えて

1

問題は、この宣言ostream& operator << (ostream& out, Media aMedia)です。パラメータaMediaをオブジェクトのスライスの原因となるコピーで受け取り、署名をostream& operator << (ostream& out, const Media& aMedia)に変更して参照を使用して受け入れます。ので、あなたがcout << *ptrを行う際に、DVDコピーがタイプMediaで作成されたスライスの

(つまりDVDをメディアにスライスされた)、今あなたがオブジェクトの種類以来printを呼び出すときMedia呼び出しが進みますMedia::printにオブジェクトスライシングhereの詳細を読むことができます。

+0

私は、変数自体を使用するのではなく、関数のオーバーロードでconst参照を使用する必要があるのはなぜか分かりませんでした。ありがとう! –

1

または仮想ディスパッチが発生するように< <にメディア&参照することによりアメディアを渡します。

Mediaオブジェクトを直接渡しています。つまり、DVDオブジェクトの新しいコピーが作成され、DVDのみの部分が破棄され、Media部分だけがaMediaパラメータになります。

は、以下を参照してください。

ostream& operator << (ostream& out, const Media& aMedia){ 
    aMedia.print(out); 
    return out; 
} 
+1

これをconstリファレンスにしてください。 – Henrik

+0

良い点は、完了 –

+0

良い、私はなぜ変数を使用するだけでなく、すべての明確な今関数をオーバーロードでconst参照を使用する必要が明確に理解していない。 ありがとう! –

関連する問題