operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名。

这是C++扩展运算符功能的方法,虽然样子古怪,但也可以理解:一方面要使运算符的使用方法与其原来一致,另一方面扩展其功能只能通过函数的方式(c++中,“功能”都是由函数实现的)。

 一、为什么使用操作符重载?
  对于系统的所有操作符,一般情况下,只支持基本数据类型和标准库中提供的class,对于用户自己定义的class,如果想支持基本操作,比如比较大小,判断是否相等,等等,则需要用户自己来定义关于这个操作符的具体实现。比如,判断两个人是否一样大,我们默认的规则是按照其年龄来比较,所以,在设计person 这个class的时候,我们需要考虑操作符==,而且,根据刚才的分析,比较的依据应该是age。那么为什么叫重载呢?这是因为,在编译器实现的时候,已经为我们提供了这个操作符的基本数据类型实现版本,但是现在他的操作数变成了用户定义的数据类型class,所以,需要用户自己来提供该参数版本的实现。

二、如何声明一个重载的操作符?
A:  操作符重载实现为类成员函数
重载的操作符在类体中被声明,声明方式如同普通成员函数一样,只不过他的名字包含关键字operator,以及紧跟其后的一个c++预定义的操作符。
可以用如下的方式来声明一个预定义的==操作符:

 class person{
private:
int age;
public:
person(int a){
this->age=a;
}
inline bool operator == (const person &ps) const;
};

实现方式如下:

 inline bool person::operator==(const person &ps) const
{
if (this->age==ps.age)
return true;
return false;
}

调用方式如下:

 #include
using namespace std;
int main()
{
person p1();
person p2();
if(p1==p2) cout<<”the age is equal!”< return ;
}

这里,因为operator ==是class person的一个成员函数,所以对象p1,p2都可以调用该函数,上面的if语句中,相当于p1调用函数==,把p2作为该函数的一个参数传递给该函数,从而实现了两个对象的比较。

B:操作符重载实现为非类成员函数(全局函数)
对于全局重载操作符,代表左操作数的参数必须被显式指定。例如:

 #include
#include
using namespace std;
class person
{
public:
int age;
public:
}; bool operator==(person const &p1 ,person const & p2)
//满足要求,做操作数的类型被显示指定
{
if(p1.age==p2.age)
return true;
return false;
}
int main()
{
person rose;
person jack;
rose.age=;
jack.age=;
if(rose==jack)
cout<<"ok"< return ;
}

C:如何决定把一个操作符重载为类成员函数还是全局名字空间的成员呢?
①如果一个重载操作符是类成员,那么只有当与他一起使用的左操作数是该类的对象时,该操作符才会被调用。如果该操作符的左操作数必须是其他的类型,则操作符必须被重载为全局名字空间的成员。
②C++要求赋值=,下标[],调用(), 和成员指向-> 操作符必须被定义为类成员操作符。任何把这些操作符定义为名字空间成员的定义都会被标记为编译时刻错误。
③如果有一个操作数是类类型如string类的情形那么对于对称操作符比如等于操作符最好定义为全局名字空间成员。

D:重载操作符具有以下限制:

(1) 只有C++预定义的操作符集中的操作符才可以被重载;

(2)对于内置类型的操作符,它的预定义不能被改变,应不能为内置类型重载操作符,如,不能改变int型的操作符+的含义;

(3) 也不能为内置的数据类型定义其它的操作符;

(4) 只能重载类类型或枚举类型的操作符;

(5) 重载操作符不能改变它们的操作符优先级;

(6) 重载操作符不能改变操作数的个数;

(7) 除了对( )操作符外,对其他重载操作符提供缺省实参都是非法的;

E: 注意点
(1)后果载操操作符首先要确定它的返回值是左值,还是右值,如果是左值最返回引用,如果是右值那就直接返回值;

(2) +号等这样的操作符没有对象可以容纳改变后值,对于这样的情况最好返回数值,否则只能要操作符体内创建临时对象用于容纳改变后的值,如果在堆中创建临时对象返回指针或者引用,在操作符函数体外还需要释放它,如果返回的对象而不是引用或者指针,那么效率是比较低的。如果返回的是数值,最好在该类的构造函数中增加对该类型数值的转换函数,如:返回值是int类型,那么最好有一个int类型作为参数的构造函数。

(3)在增量运算符中,放上一个整数形参,就是后增量运行符,它是值返回,对于前增量没有形参,而且是引用返回,示例:

 class Test
{
public:
Test(x=){ m_value = x}
Test &operator ++(); //前增量
Test &operator ++(int);//后增量
private:
Int m_value:
};
Test &Test::operator ++()
{
m_value ++; //先增量
return *this; //返回当前对象
}
Test Test::operator ++(int)
{
Test tmp(*this); //创建临时对象
m_value ++; //再增量
return temp; //返回临时对象
}

(4)因为强制转换是针对基本数据类型的,所以对类类型的转换需自定义;

(5) 转换运行符重载声明形式:operator 类型名();它没有返回类型,因为类型名就代表了它的返回类型,所以返回类型显得多余。

(6)一般来说,转换运算符与转换构造函数(即带一个参数的构造函数)是互逆的,如有了构造函数Test(int),那么最好有一个转换运算符int()。这样就不必提供对象参数重载运算符了,如Test a1(1);Test a2(2); Test a3; a3 = a1+a2;就不需要重载+号操作符了,因为对于a1+a2的运算,系统可能会先找有没有定义针对Test的+号操作符,如果没有,它就会找有没有针对Test类转换函数参数类型的+号操作符(因为可以将+号运行结果的类型通过转换函数转换为Test对象),因为Test类有个int类型的参数,对于int类型有+操作符,所以a1+a2真正执行的是Test(int(a1) + int(a2));即Test(3);

(7)对于转换运算符,还有一个需要注意的地方就是,如果A类中有以B为参数的转换函数(构造函数),那B中不能有A的转换运算符,不然就存在转换的二义性,如:

 class A{A(B&){…}}; class B{ operator A(){…}};

那么以下语句就会有问题:

 B b; A(b);//A(b)有就可能是A的构造函数,也可以是B的转换运算符

From:http://blog.sina.com.cn/s/blog_4b3c1f950100kker.html

C++中operator关键字(重载操作符)的更多相关文章

  1. [019]转--C++ operator关键字(重载操作符)

    原博客:http://www.cnblogs.com/speedmancs/archive/2011/06/09/2076873.html operator是C++的关键字,它和运算符一起使用,表示一 ...

  2. C++ operator(重载操作符) 【转】

    转自:http://www.cnblogs.com/xiangxiaodong/archive/2012/02/12/2348144.html operator是C++的关键字,它和运算符一起使用,表 ...

  3. C++ 中operator用法:隐式类型转换

    [转]C++ operator两种用法 C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator c ...

  4. C++ 友元(friend关键字)、类中的重载、操作符重载(operator关键字)

    C++ 中友元的用法: 1.在类中使用friend关键字声明 2.类的友元可以是其它类或者具体函数 3.友元不是类的一部分 4.友元不受类中访问级别的限制 5.友元可以直接访问具体类中的所有成员. 友 ...

  5. C++ operator关键字(重载操作符)(转)

    operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名. 这是C++扩展运算符功能的方法,虽然样子古怪,但也可以理解:一方面要使运算 ...

  6. C++ operator关键字(重载操作符)

    operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名.     这是C++扩展运算符功能的方法,虽然样子古怪,但也可以理解:一方面 ...

  7. 重载操作符 operator overloading 学习笔记

    重载操作符,只是另外一种调用函数的方法和表现方式,在某些情况它可以让代码更简单易读.注意不要过度使用重载操作符,除非它让你的类更简单,让你的代码更易读. 1语法 如下: 其中友元,关键字不是必须的,但 ...

  8. VC6.0中重载操作符函数无法访问类的私有成员

    整理日: 2015年03月18日 在 C++ 中,操作符(运算符)可以被重载以改写其实际操作.同时我们可以定义一个函数为类的朋友函数(friend function)以便使得这个函数能够访问类的私有成 ...

  9. C++的重载操作符(operator)介绍(转)

    本文主要介绍C++中的重载操作符(operator)的相关知识. 1. 概述 1.1 what operator 是C++的一个关键字,它和运算符(如=)一起使用,表示一个运算符重载函数,在理解时可将 ...

随机推荐

  1. Spring、基本类型属性和集合类型属性的注入

    Spring 还可以对基本属性和集合类型属性进行注入: public interface PersonIService { public String getBaseProperty(); publi ...

  2. Struts2 自定义拦截器实例—登陆权限验证

    实现一个登陆权限验证的功能 message.jsp: <body> message:${message } </body> login.jsp: <% request.g ...

  3. javascript第九课"闭包"

    所谓闭包:就是一个函数内部又定义了一个函数,而这个函数能访问外部函数作用域范围内的变量,这个内部函数就叫做闭包!   js中的面向对象都是使用闭包来实现的 闭包里使用的变量会现在当前函数内搜索,没有的 ...

  4. C# 中奇妙的函数–7. String Split 和 Join

    很多时候处理字符串数据,比如从文件中读取或者存入 - 我们可能需要加入分隔符(如CSV文件中的逗号),或使用一个分隔符来合并字符串序列. 很多人都知道使用split()的方法,但使用与其对应的Join ...

  5. 如何删除Oracle数据库

    1>点击开始找Oracle的目录,-->点击[Universal Installer],打开点击[卸载产品] 2>除了oracle_home1 不点外,其他的都勾选. 3>再点 ...

  6. ios文本常见属性

    文本属性Attributes 1.NSKernAttributeName: @10 调整字距 kerning 字距调整 2.NSFontAttributeName : [UIFont systemFo ...

  7. 应用程序无法启动,因为应用程序的并行配置不正确,有关详细信息,请参阅应用程序事件日志,或使用命令行SxsTrace.exe工具

    今天做项目,需要用C#引用C++的链接库文件,但是在调试的时候会报错这个错误. 运行SxsTrace.exe 以管理员用户登陆,启动cmd; 执行命令:SxsTrace Trace -logfile: ...

  8. NULL、空指针,’\0’,0的去区别

    http://blog.csdn.net/bailyzheng/article/details/7677628参考该博客 NULL是空指针常量.

  9. 精读《javascript高级程序设计》笔记二——变量、作用域、内存以及引用类型

    变量.作用域和内存问题 执行环境共有两种类型——全局和局部 作用域链会加长,有两种情况:try-catch语句的catch块,with语句. javascript没有块级作用域,即在if,for循环中 ...

  10. css书写顺序和常用命名推荐

    写代码的时候有一个好的规范和顺序能够帮你节省很多时间.下文将推荐相关CSS书写顺序和规范的一些方法.这个文档将会整理进前端规范文档中,如果你有更好的意见,不妨留言告知我们. CSS书写顺序 该代码来自 ...