3

クラス DVD はクラス Media を継承し、基本クラスよりも 1 つ多い変数を持ちます。

ポインターを宣言します。

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

DVD のコンテンツを印刷したいので、次のコードは期待どおりに機能します。

ptr->print(cout);

ただし、オーバーロードされた << 演算子を使用すると、基本クラスの print() 関数のみが呼び出されます。

cout << *ptr << endl;

そのため、ディレクターの名前ではなく、ID のみが出力されます。

この問題を解決する 1 つの方法は、オーバーロード << 演算子を少し変更して、ポインターを受け入れるようにすることです。

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!
} 
4

2 に答える 2

1

または、参照Media&によってaMediaを<<に渡して、仮想ディスパッチが発生するようにします。

Mediaオブジェクトを直接渡すことは、DVDオブジェクトの新しいコピーが作成され、DVDのみの部分が破棄され、そのMedia部分だけがaMediaパラメーターに含まれることを意味します。

見る:

ostream& operator << (ostream& out, const Media& aMedia){
    aMedia.print(out);
    return out;
}
于 2012-04-05T10:14:39.680 に答える
1

問題はこの宣言にありostream& operator << (ostream& out, Media aMedia)ます。aMediaオブジェクトのスライスを引き起こすコピーによってパラメータを受け入れています。署名をに変更して参照を使用してパラメータを受け入れますostream& operator << (ostream& out, const Media& aMedia)

を実行するときのスライスのために、cout << *ptrコピーDVDタイプで作成されますMedia(つまり、DVDがメディアにスライスされます) 。printオブジェクトのタイプが呼び出しであるため、を呼び出すと、Mediaに移動しMedia::printます。オブジェクトのスライスについて詳しくは、こちらをご覧ください。

于 2012-04-05T10:15:08.383 に答える