运算符>>重载到嵌套类成员的语法是否正确?

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

提问人:Yifangt 提问时间:7/14/2022 最后编辑:Yifangt 更新时间:7/14/2022 访问量:80

问:

我在 Student 中嵌套了类地址,我想通过 istream 将每个输入行都馈送到 Student中>>运算符重载。

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
...

我的链接 istream(问题行)无法解决,错误消息如下:

./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 >> ......

我在 SO 中只找到了一个类似的帖子,但它是针对“操作员<<”的,与我的需求相反。而且,这对我来说很难消化。 对于我来说,读取一行并将该行馈送到类 Student 的对象成员(尤其是嵌套类 Address)中的正确语法是什么?多谢!

C++ 嵌套 重载 iStream

评论

4赞 Borgleader 7/14/2022
imo 正确的做法是实现 Address 的运算符并从 Student 调用它。(但您也可以让您当前的操作员成为 Address 的朋友,但您需要一个前向声明才能使其工作等,它感觉不那么干净)

答:

2赞 Dmitry Kuzminov 7/14/2022 #1

问题不在于操作员本身,而在于成员的可见性。您正在将该类用作 的成员,但无法从中访问该成员(不仅对于输入运算符)。AddressStudentAddress::house_no

一种解决方案(一个简单但糟糕的解决方案)是打开以下成员:Address

class Address {
public:
    ....

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

但更好的方法是为以下项定义输入运算符: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;
}

评论

0赞 Yifangt 7/14/2022
谢谢!确认:类中的重载应该是?我也尝试过。Addressprivatepublic
0赞 Dmitry Kuzminov 7/14/2022
我的错:我已经复制了您的代码,但没有注意到另一个问题。这些运算符不是成员函数。它们是在类外部定义的自由函数。友谊不会影响可见性,因此您可以在任何部分声明它。请参阅更新。
0赞 Yifangt 7/14/2022
Address::house_no成员无法访问,这有助于我全面了解问题。多谢!Student