0

In my example, I have two classes: Parent and Child. I'm using a vector of pointers to Parent (vector<Parent*> v;) and I'm inserting objects of both classes into v. I'm trying to print the classes attributes overloading the operator <<. My code prints the Parents attributes (name and age) and I would like to know how to print the derived attributes from Parent and the Child's own attribute.

class Parent{
    friend ostream &operator<<(ostream &saida, Parent &parent){
        out << "Name: " << parent.name << ", Age: " << parent.age << "." << endl;
        return out;
    }
    public:
        Parent(string name, int age){
            this->name = name;
            this->age = age;
        }
        string& getName(){
            return name;
        }
        int& getAge(){
            return age;
        }
        
    private:
        string name;
        int age;
};

class Child: public Parent{
    friend ostream &operator<<(ostream &out, Child &child){
        out << "Name: " << child.name << ", Age: " << child.age << ", School: " << child.school << "." << endl;   
        return out;
    } // <- Don´t know what to do here

    public:
        Child(string name, int age, string school): Parent(name, age){
            this->school = school;
        }
        string& getType(){
            return type;
        }
        
    private:
        string school;
};


int main(){
    vector<Father*> v;

    v.push_back(new Parent("Father", 30));
    v.push_back(new Child("Child", 10, "School"));
    


    for(int i = 0; i < v.size(); i++){
        cout << *v[i];
    }
    return 0;

}

It prints:

Name: Father, Age: 30
Name: Child, Age: 10
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Bernardo
  • 3
  • 2
  • One way is to have the `operator<<` in the `Parent` class call a virtual function that you've defined in both `Parent` and `Child` that writes the output to a passed in `std::ostream&`. You don't need the `operator<<` in `Child` then. – Retired Ninja Dec 22 '22 at 06:45
  • 1
    Thank you, @RetiredNinja. It answears my question. – Bernardo Dec 22 '22 at 15:48

1 Answers1

1

In Parent:

    friend std::ostream &operator<<(std::ostream& out, Parent const& parent){
      parent.print(out);
      out << ".\n";
      return out;
    }
    virtual void print(std::ostream& out) const {
      out << "Name: " << name << ", Age: " << age;
    }

in Child:

    void print(std::ostream& out) const override {
      Parent::print(out);
      out << ", School: " << school;
    }

and things should work the way you want.

To use C++'s object inheritance system and get dynamic dispatch, you need to use virtual dispatch. Here, I forward the operator<< to a virtual print method.

This print method doesn't include the ".\n" on purpose; that allows children to add new fields easily.

The Child class does not have a operator<<, but uses the Parent's operator<<.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524