`
lianxiangbus
  • 浏览: 528791 次
文章分类
社区版块
存档分类
最新评论

C++中的操作符重载

 
阅读更多

在c++中,我们可以定义一个函数完成某种功能,当我们想完成的功能与通用操作符完成的功能一致时就需要进行操作符的重载来方便我们的应用。

如String类的两个对象,相加时我们可以实现append或者add函数,但是如果采用“+”会觉得更加方便。

所以我们重载+操作符,而不是定义其它的函数(注意,c++中赋值“=”,成员访问“->”,下标“[]“,调用操作符“()”只能在重定义为类成员函数,而不能定义为非成员操作符重载)

void operetor+(const String&,const String& )const{ };//类似于函数的重载,只是使用了关键字operator;

分类:操作符重载费为类成员操作哦符重载和非类成员操作符重载:

两种操作符重载:类成员操作符重载和非类成员操作符重载。

  1、类成员操作符重载

  已知类String中声明了两个“==”操作符重载,分别是:

  bool operator==(const char*) const;

  bool operator==(const String&) const;

  其中第一个重载的操作符允许我们比较一个String类对象是否等于一个C风格字符串,第二个允许我们比较两个String类对象是否相等。

  示例代码

  :

  #include<String.h>

  int main()

  {

  String flower;

  If(flower==”lily”) //正确:调用bool operator==(const char*) const;

  ……

  else

  if(“tulip”==flower) //错误

  …….

  }

  关键看一下,为什么第二个重载操作符的使用是错误的?

  因为:只有在左操作数是该类类型的对象时,才会考虑使用作为类成员的重载操作符。

  因为这里的”tulip”不是String类型对象,所以编译器试图找到一个内置操作符,它可以有一个C风格字符串的左操作数,然而事实上并不存在这样的操作符,所以编译时产生错误。

  疑问:我们可以使用String类的构造函数将一个C风格字符串,转换成一个String对象,为什么编译器不能做以上转换呢?即

  if(String(“tulip”)==flower);//这样就是正确的

  答:为了效率和正确性

  重载操作符并不要求两个操作数的类型一定相同。可能有这样一个类Text,这个类的构造函数的参数及其成员重载操作符的参数都与String类一致,如果使编译器能够自动将C风格字符串转换成某个类型的对象,那么编译器首先会检索所有的类定义,选择能够提供正确构造函数和重载操作符的类进行转换,这无疑会增加程序的编译时间,还有就是类String和类Text均合适,编译器也不知道该将C风格字符串转换成String还是Text对象了。

  对于类成员重载操作符,隐式的this指针被用作隐式的第一个参数,对于成员操作符,flower==”lily”会被编译器重写为:flower.operator==(“lily”);

  2、非类成员操作符重载

  为了解决上面的问题,我们可以考虑使用非类成员操作符代替类成员操作符,这样做的好处是左操作数不必非要是某个类的类型对象了,对于需要两个操作数的操作符重载,我们就可以定义两个参数了。比如:

  bool operator==(const String&,const String&);

  bool operator==(const String&,const char*);

  可以看到,这两个全局重载操作符比成员操作符多了一个参数,这样定义之后,还是上面的代码,当调用flower==”lily”时,会调用上面的bool operator==(const String&,const char*);

  然而“tulip”==flower会调用哪个操作符重载呢,我们并没有定义bool operator==(const char*,const String&);,我们是不是必须定义这样一个全局操作符重载呢?答案是否定的,因为当一个重载操作符是一个名字空间函数时,对于操作符的第一个和第二个参数,即等于操作符的左右两个操作数都会考虑转换,就像int vi=1; double vd=2.0; vi=vi+vd; 会先将vd转换成int型,再做加法一样这意味着,编译器将解释第二个用法如下:

  bool operator==(String(“tulip”),flower)。这样会增加系统转换开销。

  因此,如果需要频繁比较C风格字符串和String对象,那么最好定义上面的操作符重载,如果不频繁,我们只需定义下面一个就够了:

  bool operator==(const String&,const String&);

 

 注:(1)如果一个重载操作符是类成员,那么只有当跟它一起使用的左操作数是该类对象时,它才会被调用,如果该操作符的左操作数必须是其他类型,那么重载操作符必须是非类成员操作符重载。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics