运算符重载(operator overload) 是c++的一个重要的新特性,它使得程序员把c++运算符定义扩展到操作数是对象的情况.运算符重载的目的是使c++程序更加直观,更易懂.运算符重载和普通的重载一样:作用域相同,函数名字相同,但参数不同(参数个数,参数的类型) , 注意如果函数名字相同,参数相同但函数的返回值类型不同这不是重载,这是错误!返回值类型operator 被重载的运算符(参数...){函数的实现}具体的例子网上有很多, 我的重点是一些我们在写重载中易忽略的一些小问题.有时候我们的程序在多数情况下是对的但有时也总有一些出乎我们意料的情况: 请看下面这个程序:#include<iostream>#include<stdlib.h>using namespace std;int/*explicit*/ add(int a,int b) //1{cout<<"int int"<<endl;return a+b;}float/*explicit*/add(float a,float b) //2{cout<<"float float"<<endl;return a+b;}int main(){cout<<add(1,1)<<endl; //这里完全匹配没有问题//cout<<add(1.1,2.0)<<endl; //这里编译器编译的时候会有歧义cout<<add(1.1,2)<<endl; //问题出现这里编译器会有一个隐式类型转换//编译器会把1.1向下隐式转换为1 (double->int)//这里编译器不会把2向上转换即(int->double) 这的强者类型转换//呵呵恐怖吗你以为你在调用第二个函数结果调用的是第一个system("pause");}运算结果:我本以为第二个cout会调用第二个函数结果, 但结果程序调用的是第一个这里涉及到类型转换编译器默认会把 1 .1 -> 1 (double->int) 向下转换.而不是把2->2.0 (int -> double ) 这样是强制类型转换.那么如何避免编译器的隐藏类型转换了那就是explicit (清晰的) 关键字这个关键字的作用是告诉编译器禁止默认的类型转换, 从而导致一些非法的参数被默认转换成为合法的参数. 我在opencv的头文件中见到了很多这个关键字可见这个关键字还是很重要的.加了以后编译器会报错下面是一个运算符重载的例子:#include<iostream>#include<stdlib.h>using namespace std;class Complex{public:Complex(){real=0,image=0;};Complex(double,double);Complex operator++(int);Complex& operator++();Complex& operator--();Complex operator+(const Complex &);Complex operator-(const Complex &);Complex operator*(const Complex &);//Complex& operator+=(Complex &);//Complex& operator-=(Complex &);//iostream & operator<<(iostream &);//iostream & operator>>(iostream &);double getReal();double getimage();//private:double real;double image;};Complex::Complex(double r,double i){real=r;image=i;};Complex& Complex::operator++(){real++;image++;return *this;}Complex Complex::operator++(int a){Complex temp=*this;real++;image++;return temp;}Complex& Complex::operator--(){real--;image--;return *this;};Complex Complex::operator+(const Complex &a) {return Complex(real+a.real,image+a.image); };Complex Complex::operator-(const Complex &a) {return Complex(real-a.real,image-a.image); };Complex Complex::operator*(const Complex &a) {return Complex(real*a.real,image*a.image); };/*Complex& Complex::operator+=(Complex &a) {real+=a.real;image+=a.image;return *this;};*//*Complex& Complex::operator-=(Complex &a) {real-=a.real;image-=a.image;return *this;Complex& operator+=(Complex &a,const Complex &b) {a.real+=b.real;a.image+=b.image;return a;};Complex& operator-=(Complex &a,const Complex &b) {a.real-=b.real;a.image-=b.image;return a;};ostream &operator<<( ostream &out,const Complex &a) {//out<<"("<<a.real<","<<a.image<<")"<<endl;out<<"("<<a.real<<","<<a.image<<")";return out;};istream &operator>>(istream &in,Complex &a){in>>a.real>>a.image;return in;};int main(){Complex a;cout<<"请输入一个复数:"<<endl;cin>>a;cout<<"你输入的数是:"<<a<<endl;Complex b;cout<<"a:"<<a<<" b:"<<b<<endl;b=a++;cout<<"b=a++ :"<<b<<endl;cout<<"a:"<<a<<" b:"<<b<<endl;b=++a;cout<<"b=++a :"<<b<<endl;b=Complex(10,10);Complex c;c=a+b;cout<<"a:"<<a<<" b:"<<b<<endl;cout<<"a+b:"<<c<<endl;c=a-b;cout<<"a:"<<a<<" b:"<<b<<endl;cout<<"a-b: "<<c<<endl;c=a*b;cout<<"a:"<<a<<" b:"<<b<<endl;cout<<"a*b: "<<c<<endl;cout<<"a:"<<a<<" b:"<<b<<endl;a+=b;cout<<"a+=b: "<<a<<endl;cout<<"a:"<<a<<" b:"<<b<<endl;a-=b;cout<<"a-=b: "<<a<<endl;//#ifndef COMPLEX_H//cout<<"error!!"<<endl;//#endifsystem("pause");return 0;}可能有人会说这个程序有什么特别的呢?你可能会注意到这个程序里有好多引用& , 但有的函数返回值前加上了引用,有的没有加.我先说一下,可能有些人不知道为什么要加引用,有时候在函数传参时加不加结果都是那,的确你的程序并没有错.如果不加引用,一个函数在传参数的时候和返回的时候都会调用该对象所属类的拷贝构造函数构造出一个临时对象出来,如果这个类不是很复杂的话这点开销也许不算什么.但如果这个类很复杂的话这点开销你就得注意了.所有能加引用的地方尽量就使用它把.但我写的上面这个程序为什么有的地方没有加引用了?你仔细看就会发现这些函数的返回值,都有一个共性就是他们都返回了一个在该函数中创建的一个局部的变量. 该对象(变量) 在函数返回时生命周期结束,它所占用的内存空间就会被释放掉, 你所返回的东西已经不存在了所以这里千万不能叫引用.不加引用函数在返回时会构造出另为一个改类的对象,新对象的作用域和调用它的地方所在的作用域相同,所有你就可以使用这个新的对象了.。