c++classnestedoverloadingistream

Correct syntax for operator >> overloading to members of nested class?


I have class Address nested in class Student, and I want to feed each input line into the class Student with operator>> overloading through istream.

class Address {
public:
    ....

private:
    int house_no;
    string street;
    string city;
    string postcode
};


class Student {
public:
    ....
    friend istream& operator>>(istream& iss, Student& Obj) {
        iss >> Obj.roll_no >> Obj.name 
       >> Obj.addr.house_no >> Obj.addr.street >> Obj.addr.city >> addr.postcode;    //problem line
        return iss;
}

private:
    int roll_no;
    string name;
    Address addr;
};


//Sample line of test data (fields delimiter is comma):
1101, Alice Rilley, 421, Main St., New York, 230011
2202, Bert McDonald, 152, Railroad St., Madison, 120022
...

My chained istream (problem line) did not work out with error message as:

./include/Student.h: In function ‘std::istream& operator>>(std::istream&, Student&)’:
./include/Student.h:23:60: error: ‘int Address::house_no’ is private within this context
   23 |                 iss >> Obj.roll_no >> Obj.name >> Obj.addr.house_no >> ......

I found only one similar post in SO, but it is for "operator << " opposite to my need. And, it was quite difficult for me to digest. What is the correct syntax for me to read in a line and feed the line into the object members (especially the nested class Address) of class Student? Thanks a lot!


Solution

  • The problem is not in the operator itself, but in the visibility of the members. You are using the Address class as a member of Student, but the Address::house_no member is not accessible from it (not only for the input operator).

    One solution (a simple but bad one) would be to open the members of Address:

    class Address {
    public:
        ....
    
    //private:
    public:
        int house_no;
        string street;
        string city;
        string postcode
    };
    

    But a better approach would be to define an input operator for Address:

    class Address {
    public:
        ....
    
    private:
        friend istream& operator>>(istream& iss, Address& Obj);
    
        int house_no;
        string street;
        string city;
        string postcode
    };
    
    
    class Student {
    public:
        ....
        friend istream& operator>>(istream& iss, Student& Obj);
    
    private:
        int roll_no;
        string name;
        Address addr;
    };
    
    istream& operator>>(istream& iss, Address& Obj) {
        iss >> Obj.house_no >> Obj.street >> Obj.city >> Obj.postcode;
        return iss;
    }
    
    istream& operator>>(istream& iss, Student& Obj) {
        iss >> Obj.roll_no >> Obj.name >> Obj.addr;
        return iss;
    }