C++中不使用friend函数能否重载<<和>>运算符?
可以不使用friend函数重载<<和>>运算符
我们平时优先用friend重载这两个运算符,本质是要让运算符函数有权限访问类的私有成员,只要解决了访问权限问题,完全可以不用friend实现。
- 最常用的无friend实现方案:给自定义类添加公有的读(get)、写(set)接口,重载运算符的全局函数直接调用这些公有接口完成成员的读写,不需要把运算符函数声明为类的友元,示例代码如下:
#include <iostream> #include <string> class Person { private: std::string name; int age; public: Person(std::string n, int a) : name(n), age(a) {} // 公有读接口,供外部读取私有成员 std::string getName() const { return name; } int getAge() const { return age; } // 公有写接口,供外部修改私有成员 void setName(std::string n) { name = n; } void setAge(int a) { age = a; } }; // 全局函数重载<<,不需要friend声明 std::ostream& operator<<(std::ostream& os, const Person& p) { os << "姓名:" << p.getName() << ",年龄:" << p.getAge(); return os; } // 全局函数重载>>,不需要friend声明 std::istream& operator>>(std::istream& is, Person& p) { std::string name; int age; is >> name >> age; p.setName(name); p.setAge(age); return is; }
- 不推荐的实现方式:将<<、>>运算符重载为类的成员函数。这种写法虽然也能实现功能,但是调用时左操作数必须是类实例,语法会变成
自定义对象 << std::cout,和常规使用的流调用顺序相反,可读性非常差,实际开发中基本不会用。
两种实现的选择建议:
如果你优先考虑代码简洁度,且确定运算符函数只会访问你要暴露的类成员,用friend重载的写法更精简;如果你优先考虑类的封装性,不希望私有成员直接暴露给外部函数,就用公有接口+全局重载的无friend方案。
内容的提问来源于stack exchange,提问作者Amit Pant
相关产品推荐
相关产品推荐

