C++重载<<和>>运算符实现类内容读写的运行原理疑问
问题解答
核心原理:二元运算符重载的参数映射规则
首先你要明确,C++中二元运算符的重载分两种实现形式,参数对应规则完全不同:
- 重载为类的成员函数:表达式
A op B会被编译器转换为A.operator op(B),此时左操作数A必须是该类的实例,参数只需要传右操作数B - 重载为非成员函数(含友元声明的全局函数):表达式
A op B会被编译器转换为operator op(A, B),左右操作数都会作为参数传入函数
你给IO流重载的>>/<<运算符就是典型的非成员函数实现,原因很简单:左操作数是标准库的std::istream/std::ostream类型对象,我们没法修改标准库的流类来新增成员函数,只能用非成员函数的形式实现重载。
对应到你的代码的调用逻辑
你写的std::cout << emp1语句,编译器的处理流程是:
- 识别到这是二元
<<运算符表达式,左操作数是std::ostream类型的全局对象std::cout,右操作数是你自定义的Employee类对象emp1 - 查找所有匹配的
operator<<重载,刚好匹配到你声明的友元全局函数:std::ostream& operator << (std::ostream& s, Employee& e) - 自动把左操作数
std::cout绑定到第一个参数s,右操作数emp1绑定到第二个参数e,完成函数调用,等价于你手动写了operator<<(std::cout, emp1) - 函数返回
std::ostream&也就是s的引用(也就是std::cout本身的引用),所以支持链式调用,比如你代码里的std::cout << "Employee 1 is: \n" << emp1,本质就是先调用operator<<(std::cout, "Employee 1 is: \n")返回cout的引用,再用这个返回值作为左操作数调用operator<<(返回的cout引用, emp1)
补充优化建议
你的输出运算符实现里第二个参数应该加const修饰,改为std::ostream& operator << (std::ostream& s, const Employee& e),因为输出操作不会修改Employee对象的内容,加const之后你可以输出const修饰的Employee实例,兼容性更强。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

