运算符重载能否无需友元访问私有成员?重载正确性咨询
关于C++运算符重载与私有成员访问的疑问解答
问题1:运算符重载是否允许不通过友元访问私有成员?
当然可以,但这取决于你把运算符重载写成类的成员函数还是全局非成员函数:
- 如果是类的成员函数来重载运算符:成员函数本身属于类的一部分,天然拥有访问类内所有私有/保护成员的权限,包括同类型其他对象的私有成员,完全不需要友元。
- 如果是全局非成员函数来重载运算符:这时候函数不属于类的范畴,要访问类的私有成员,就必须通过友元声明来获取权限。
问题2:为什么代码未使用友元却能访问私有成员?运算符重载是否规范?
首先解释为什么没报错:
你写的operator+应该是Person类的成员函数对吧?比如类似这样的代码:
class Person { private: int id; public: Person(int id) : id(id) {} // 成员函数版本的+运算符重载 Person operator+(const Person& p) { return Person(this->id + p.id); } };
C++的类成员函数有一个特殊规则:同类型的所有对象,它们的成员函数可以互相访问彼此的私有成员。这是语言本身的设计,并没有违反封装原则——因为成员函数是类对外暴露的接口的一部分,类的设计者已经允许这个函数操作类的内部数据,不管是当前对象还是其他同类型对象。
然后说规范问题:
你的写法是完全规范的!教材里提到的“访问私有成员需要友元”,是针对全局非成员函数版本的运算符重载而言的。比如如果你想支持int + Person这种左操作数不是类对象的场景,就必须把operator+写成全局函数,这时候才需要友元来访问私有成员。而对于Person + Person这种左操作数是类对象的场景,成员函数版本是非常标准的写法,很多教材也会优先介绍这种方式。
内容的提问来源于stack exchange,提问作者ajayramesh
相关产品推荐
相关产品推荐

