C++运算符重载的三个为什么

C++运算符重载的三个为什么

1. 为什么有四个操作符不宜重载为友元函数?

四个不能宜载为友元函数的运算符为:=、()、[]、->

我在网上搜了许多博客,很多人都说是:
当把赋值运算符重载为类的友员函数,在程序中执行类对象的赋值语句时,程序就会出现两种矛盾的选择。

(1)因为它认为类中并没有重载赋值运算符的成员函数,所以它根据C++的规则,会去调用相应的构造函数。

(2)但是在全局里,我们已经重载了参数类型为此类类型的赋值运算符函数,而这赋值语句刚好和这函数匹配上了,根据C++的规则,也会去调用这函数。

程序是不允许有矛盾不确定选择的,所以当赋值运算符重载为类的友元函数时,编译器就会提示错误。

对于剩下的3个运算符 ->, [], () 为什么不能重载为友元函数,也是跟上面一样的道理。即编译器发现当类中没有定义这3个运算符的重载成员函数时,就会自己加入默认的运算符重载成员函数。

然而,上面的解释是有问题的。它的大概意思就是因为编译器对上述四个操作符有默认的运算符重载成员函数。在这种情况下若是用户把上述四个运算符重载为类的友元函数,则会引起编译器不知道用默认的还是用友元重载,所以会出错。
但是在C++中的六个默认的成员函数当中并没有()、[]和->,所以编译器并不会对()、[]和->产生默认的运算符重载成员函数

按照我的理解:
C++对运算符重载有如下要求:

1. 不能改变运算符操作数的个数
2. 不能改变运算符原有的优先级
3. 不能改变运算符原有的结合性
4. 不能改变操作符原有的语法结构

四个运算符=、()、[]、->它们的语法结构为:运算符左侧必须为一个变量或者对象。若是重载为类的成员函数正好符合这一点;但是若重载为类的友元函数,则可能会这样一种情况:重载时在形参列表中调换了两个参数的顺序,导致形参列表中的第一个参数不是要调用该运算符的变量或者对象,就对改变了操作符原有的语法结构。所以编译器会报错。

2. 为什么流操作符必须重载为友元函数?

如果是重载双目操作符(即为类的成员函数),就只要设置一个参数作为右侧运算量,而左侧运算量就是对象本身。而 >> 或<< 左侧运算量是 cin或cout 而不是对象本身,所以不满足后面一点,就只能申明为友元函数了。

如果重载为类的成员函数,在调用时必然会出现这种情况:cout << object;, 在编译器编译时就会解释为:cout.opreator <<(Class & object);。这明显是错误的。

另外,大部份的标准库实现中,对ostream,istream类体系采用了构造函数保护继承的方式。致使即使以继承的方式来扩展流类,也会在对象实例化时遭遇阻碍。
另一方面,标准库中的流类,其插入符函数没有声明为虚函数,因此子类不能对其实现进行覆盖,所以也使成员函数重载遭遇到实质的困难。

3. 为什么有五个操作符不能重载?

四个不能重载的操作符为:.、.*、::、?:、sizeof

前两个运算符不能重载是为了保证访问成员的功能不能被改变,域运算符合sizeof运算符的运算对象是类型而不是变量或一般表达式,不具备重载的特征。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值