How do I call function overloading from the base class (not abstractly)?

The DVD class inherits from the Media class and has one more variable than the base class.

I declare a pointer:

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

      

I want to print the contents of the DVD, so the following code works as expected:

ptr->print(cout);

      

But using the overloaded <operator only calls the print () function of the base class:

cout << *ptr << endl;

      

This way it only prints the ID and not the director's name.

One way to solve this problem is to change the overload of the <operator to make it accept pointers, so:

cout << ptr << endl;

      

should work, but somehow I have to find a way to make it cout << *ptr << endl;

work as expected.

Any advice?

The fact is that I cannot abstract from the base class (Media), because I need to call its instance in the ostream overload operator, so the base class pointer cannot call the overload function of the derived class it points to.

code:

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

      

+3


source to share


2 answers


The problem lies in this declaration ostream& operator << (ostream& out, Media aMedia)

. You take a aMedia

copy parameter that causes the object to be clipped, takes it by reference, changing the signature to ostream& operator << (ostream& out, const Media& aMedia)

.



Because of the slice, when you do cout << *ptr

, a copy of the DVD

type is created Media

(that is, the DVD is ripped to media), now when you call print

, since the type object the Media

call goes to Media::print

. You can read more about object separation here .

+1


source


Or pass aMedia on the Media & link before <so that virtual dispatch happens.

You are passing the Media object directly, which means a new copy of the DVD object will be created and only parts of the DVD will be thrown and only parts of their media will go into the aMedia parameter.



cm

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

      

+1


source







All Articles