在继承的类中重载<<和>>

Phi*_*hil 3 c++ inheritance overloading operators

我有类Person(名字,姓氏,地址,年龄)和重载运算符<<和>>来与文件流一起使用:

ostream& operator<< (ostream& outStream, Person& person)
{
  ...
}

istream& operator>> (istream& inStream, Person& person)
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

它工作正常 - 我可以轻松地读取和写入文件,但我添加了两个继承自Person:Student和Worker的类.

我为他们编写了重载操作符,与上面的操作符非常相似:

ostream& operator<< (ostream& outStream, Worker& worker)
{
 ...
}

istream& operator>> (istream& inStream, Worker& worker)
{
 ...
}


ostream& operator<< (ostream& outStream, Student& student)
{
 ...
}

istream& operator>> (istream& inStream, Student& student)
{
 ...
}
Run Code Online (Sandbox Code Playgroud)

唯一不同的是每个班级还有两个字段.问题是,当我使用Student或Worker重载运算符时,我的编译器似乎使用运算符.可能它会从Student或Worker到Person进行隐藏转换,但结果是没有写入该文件的其他字段.offstream <<人们的工作与流出的<<学生或外来工人一样.也许首先为继承的类放置重载的运算符声明,然后在代码中为Person解决问题,但我不认为它是一个优雅的解决方案.

如果您有一些想法如何解决上述问题,我将不胜感激.

Bjö*_*lex 12

两件事情.首先,让你的运算符接受const的引用,如下所示:

ostream& operator<< (ostream& outStream, const Person& person)
Run Code Online (Sandbox Code Playgroud)

要解决您的问题,常见的模式是为您的类型提供受保护的虚拟toString方法,并让操作员调用它.然后,您可以在子类中重载此方法,如果您只想在字符串中附加一些值,甚至可以重用超类实现.

例:

class Person {
// other stuff
protected:
    virtual std::string toString();
    friend ostream& operator<< (ostream& outStream, const Person& person)
};

ostream& operator<< (ostream& outStream, Person& person)
{
    ostream << person.toString();
    return outStream;
}
Run Code Online (Sandbox Code Playgroud)

编辑 其实,我更喜欢larsmans的建议:

class Person {
// other stuff
protected:
    virtual void print(ostream & stream) const;
    friend ostream& operator<< (ostream& outStream, const Person& person)
};

ostream& operator<< (ostream& outStream, Person& person)
{
    person.print(outStream);
    return outStream;
}
Run Code Online (Sandbox Code Playgroud)

这比toString想法更容易实现,因为你不需要临时stringstream或类似的东西来构建字符串.

  • 或者受保护的成员`virtual void print(std :: ostream&)const`和`virtual void read(std :: istream&)`. (5认同)