1.运算符重载规则:
>重载运算符时,参数必须是自定义类类型或者枚举类型
>运算符的优先级和结合性保持不变
>&& || 如果对逻辑运算符进行重载,则其不再具备短路求值特性(一般不推荐重载逻辑运算符)
>不能臆造一个并不存在的运算符 @ # ¥
2.能重载的运算符有很多,不能重载的运算符有: . .* ?: :: sizeof
3.>1.推荐以自由函数形式进行重载
+ - * /
//当执行完毕之后,左操作数和右操作数没有发生变化,就要使用const进行保护,如:
Complex operator +( const Complex &lhs,const Complex &rhs)
举一个+的例子, - * / 类似
////// @file Complex.cc/// @author miaobeihai(452686191@gmail.com)/// @date 2017-04-17 11:25:32///#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;class Complex
{
public:Complex(double dreal, double dimag): _dreal(dreal), _dimag(dimag){}void print(){if(_dreal == 0){if(_dimag == 0)cout << 0 << endl;elsecout << _dimag << "i" << endl;}else {cout << _dreal;if(_dimag > 0)cout << " + " << _dimag << "i" << endl;else if(_dimag < 0)cout << " - " << _dimag * (-1) << "i" << endl;elsereturn;}}double getReal()const{return _dreal;}double getImage()const{return _dimag;}private:double _dreal;double _dimag;
};//运算符重载采用的是 自由函数
Complex operator +(const Complex & lhs, const Complex & rhs)
{//return Complex(lhs._dreal + rhs._dreal, lhs._dimag + rhs._dimag);return Complex(lhs.getReal() + rhs.getReal(), lhs.getImage() + rhs.getImage());
}int main(void)
{int a = 1, b = 2;int c = a + b;Complex c1(0, -2);c1.print();Complex c2(5, -6);c2.print();Complex c3 = c1 + c2;cout << "c1 + c2 = "; c3.print();return 0;
}
#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;class Complex
{
public:Complex(double dreal = 0, double dimag = 0): _dreal(dreal), _dimag(dimag){}void print(){if(_dreal == 0){if(_dimag == 0)cout << 0 << endl;elsecout << _dimag << "i" << endl;}else {cout << _dreal;if(_dimag > 0)cout << " + " << _dimag << "i" << endl;else if(_dimag < 0)cout << " - " << _dimag * (-1) << "i" << endl;elsereturn;}}//运算符重载以成员函数的形式 Complex operator + (const Complex & rhs){return Complex(this->_dreal + rhs._dreal, this->_dimag + rhs._dimag);}private:double _dreal;double _dimag;
};int main(void)
{Complex c1(0, -2);c1.print();//Complex c2 = c1 + 5;//Right, 其调用形式为c1.operator+(5);//c2.print();//Complex c2 = 5 + c1;//Error, 这里的+ 解释为int的加法//c2.print();return 0;
}
>2.推荐以成员函数形式进行重载
+= -= *= /= %=
++ -- =
() 函数调用运算符 函数对象
[] 下标访问运算符
operator new/delete
#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;class Complex
{friend Complex operator +(const Complex & lhs, const Complex & rhs);
public:Complex(double dreal = 0, double dimag = 0): _dreal(dreal), _dimag(dimag){}void print(){if(_dreal == 0){if(_dimag == 0)cout << 0 << endl;elsecout << _dimag << "i" << endl;}else {cout << _dreal;if(_dimag > 0)cout << " + " << _dimag << "i" << endl;else if(_dimag < 0)cout << " - " << _dimag * (-1) << "i" << endl;elsereturn;}}//采用成员函数形式进行重载//返回值是引用Complex & operator+=(const Complex & rhs){cout << "Complex & operator+=(const Complex &)" << endl;this->_dreal += rhs._dreal;this->_dimag += rhs._dimag;return *this;}//前缀++,返回值是引用Complex & operator++(){++_dreal;++_dimag;return *this;}//后缀++ ,其返回值是对象Complex operator++(int) //int并不代表参数,只是一个标记,表示其是后缀++{Complex tmp(*this);++_dimag;++_dimag;return tmp;}private:double _dreal;double _dimag;
};//运算符重载采用的是 友元函数
#if 0
Complex operator+(const Complex & lhs, const Complex & rhs)
{return Complex(lhs._dreal + rhs._dreal, lhs._dimag + rhs._dimag);
}
#endif //自由函数
Complex operator+(const Complex & lhs, const Complex & rhs)
{Complex tmp(lhs);tmp += rhs;return tmp;
}int main(void)
{int a = 1, b = 2;int c = a + b;a += b;// a = a + ba++;//后缀++的值是a变化之前的值++a;//前缀++的值是a变化之后的值Complex c1(1, -2);c1.print();Complex c2(5, -6);c2.print();#if 0Complex c3 = c1 + c2;cout << "c1 + c2 = "; c3.print();c1 += c2;c1.print();
#endifcout << endl << endl;Complex c4 = 5 + c1;//5进行了隐式转换cout << "c4 = ";c4.print();return 0;
}
#include <iostream>
using std::cout;
using std::endl;class Demo
{
public:double operator()(double x, double y){return x > y ? x : y;}double operator()(double x, double y, double z){return (x + y) * z;}
};int main(void)
{Demo demo;cout << demo(3.3, 5.5) << endl;//函数对象 functor(仿函数)cout << demo(1.2, 2.1, 4) << endl;return 0;
}
>3.以友元函数形式进行重载
<< 输出流运算符
cout << a ;//左操作数是一个流对象,右操作数是输出的对象
std::ostream &operator <<( std::ostream &os ,const Complex &rhs)
>> 输入流运算符
std::istream &operator >>(std::istream &is,Complex &rhs) //不加入const是因为输入可能要对其进行修改
#include <stdio.h>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;class Complex
{friend Complex operator +(const Complex & lhs, const Complex & rhs);
public:Complex(double dreal = 0, double dimag = 0): _dreal(dreal), _dimag(dimag){}void print(){if(_dreal == 0){if(_dimag == 0)cout << 0 << endl;elsecout << _dimag << "i" << endl;}else {cout << _dreal;if(_dimag > 0)cout << " + " << _dimag << "i" << endl;else if(_dimag < 0)cout << " - " << _dimag * (-1) << "i" << endl;elsereturn;}}//采用成员函数形式进行重载//返回值是引用Complex & operator+=(const Complex & rhs){this->_dreal += rhs._dreal;this->_dimag += rhs._dimag;return *this;}//前缀++,返回值是引用Complex & operator++(){++_dreal;++_dimag;return *this;}//后缀++ ,其返回值是对象Complex operator++(int) //int并不代表参数,只是一个标记,表示其是后缀++{Complex tmp(*this);++_dimag;++_dimag;return tmp;}//流对象不能进行复制,所以返回值类型只能是流对象的引用//如果以成员函数形式进行重载,则其左操作数是Complex对象,而不是//流对象,这与输出流运算符的要求不符,所以输出流运算符不能以成员函数形式进行重载//std::ostream & operator<<();friend std::ostream & operator << (std::ostream & os, const Complex & rhs);friend std::istream & operator >> (std::istream & is, Complex & rhs);private:double _dreal;double _dimag;
};//输出流运算符
std::ostream & operator << (std::ostream & os, const Complex & rhs)
{if(rhs._dreal == 0){if(rhs._dimag == 0)os << 0;elseos << rhs._dimag << "i";}else {os << rhs._dreal;if(rhs._dimag > 0)os << " + " << rhs._dimag << "i";else if(rhs._dimag < 0)os << " - " << rhs._dimag * (-1) << "i";}return os;
}//输入流运算符
std::istream & operator >> (std::istream & is, Complex & rhs)
{is >> rhs._dreal;while(is.get() !='*');is >> rhs._dimag;return is;
}//自由函数
Complex operator+(const Complex & lhs, const Complex & rhs)
{Complex tmp(lhs);tmp += rhs;return tmp;
}int main(void)
{int a = 1, b = 2;cout << "a = " << a << ", b = " << b << endl;Complex c1(1, -2);Complex c2(3, -6);cout << "c1 = " << c1 << endl;cout << "c2 = " << c2 << endl;cout << "c1 + c2 = " << c1 + c2 << endl;cout << "pls input a Complex number:\n";Complex c3;cin >> c3;cout << "c3 = " << c3 << endl;return 0;
}
一个string类的例子
////// @file w_String.h/// @author miaobeihai(452686191miao.com)/// @date 2017-04-19 09:00:00///#ifndef __STRING_H__
#define __STRING_H__
#include <stdio.h>
#include <string.h>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;class String
{
public:String();String(const char* pstr);String(const String& rhs);~String();String& operator=(const String& rhs);String& operator=(const char* pstr);String& operator+=(const String& rhs);String& operator+=(const char* pstr);char& operator[](std::size_t index);//(const String * const this)const char& operator[](std::size_t index) const;std::size_t size() const;const char* c_str() const;#if 0friend bool operator==(const String& lhs, const String& rhs);friend bool operator!=(const String& lhs, const String& rhs);friend bool operator<(const String& lhs, const String& rhs);friend bool operator>(const String& lhs, const String& rhs);friend bool operator<=(const String& lhs, const String& rhs);friend bool operator>=(const String& lhs, const String& rhs);
#endiffriend std::ostream& operator<<(std::ostream& os, const String& s);friend std::istream& operator>>(std::istream& is, String& s);private:char* _pstr;
};String operator+(const String& lhs, const String& rhs);
String operator+(const String& lhs, const char* pstr);
String operator+(const char* pstr, const String& rhs);
#endif
////// @file String.cc/// @author lemon(haohb13@gmail.com)/// @date 2017-04-20 09:49:56///#include "String.h"
#include <string.h>
#include <iostream>
using std::cout;
using std::endl;String::String()
: _pstr(new char[1])
{_pstr[0] = '\0';
}String::String(const char * pstr)
: _pstr(new char[strlen(pstr) + 1])
{strcpy(_pstr, pstr);
}String::String(const String & rhs)
: _pstr(new char[rhs.size() + 1])
{strcpy(_pstr, rhs._pstr);
}String::~String()
{delete [] _pstr;
}String & String::operator=(const String & rhs)
{if(this != &rhs){//tmp的创建相当于直接对右操作数进行了复制String tmp(rhs);char * p = _pstr;_pstr = tmp._pstr;tmp._pstr = p;}return *this;
}String & String::operator=(const char * rhs)
{String tmp(rhs);*this = tmp;return *this;
}String & String::operator+=(const String & rhs)
{char * ptmp = new char[size() + rhs.size() + 1];strcpy(ptmp, _pstr);strcat(ptmp, rhs._pstr);delete [] _pstr;_pstr = ptmp;return *this;
}String & String::operator+=(const char * rhs)
{String tmp(rhs);*this += tmp;return *this;
}std::size_t String::size() const
{return strlen(_pstr);
}const char* String::c_str() const
{return _pstr;
}String operator+(const String& lhs, const String& rhs)
{//String tmp(lhs);String tmp;tmp += lhs;tmp += rhs;return tmp;
}
String operator+(const String& lhs, const char* pstr)
{String tmp(pstr);tmp += lhs;return tmp;
}
String operator+(const char* pstr, const String& rhs)
{String tmp(pstr);tmp += rhs;return tmp;
}std::ostream& operator<<(std::ostream& os, const String& s)
{os << s._pstr;return os;
}std::istream& operator>>(std::istream& is, String& s)
{char buff[65536] = {0};//在栈上开辟缓冲区is >> buff;delete [] s._pstr;s._pstr = new char[strlen(buff) + 1];strcpy(s._pstr, buff);return is;
}