运算符重载详情

•为了使对用户自定义数据类型的数据的操作与内置的数据类型的数据的操作形式一致,C++提供了运算符的重载,通过把C++中预定义的运算符重载为类的成员函数或者友元函数,使得对用户的自定义数据类型的数据—对象的操作形式与C++内部定义的类型的数据一致。

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;
			else
				cout << _dimag << "i" << endl;
		}
		else {
			cout << _dreal;
			if(_dimag > 0)
				cout << " + " << _dimag << "i" << endl;
			else if(_dimag < 0)
				cout << " - " << _dimag * (-1) <<  "i" << endl;
			else
				return;
			
		}
	}

	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;
			else
				cout << _dimag << "i" << endl;
		}
		else {
			cout << _dreal;
			if(_dimag > 0)
				cout << " + " << _dimag << "i" << endl;
			else if(_dimag < 0)
				cout << " - " << _dimag * (-1) <<  "i" << endl;
			else
				return;
			
		}
	}

	//运算符重载以成员函数的形式 
	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;
			else
				cout << _dimag << "i" << endl;
		}
		else {
			cout << _dreal;
			if(_dimag > 0)
				cout << " + " << _dimag << "i" << endl;
			else if(_dimag < 0)
				cout << " - " << _dimag * (-1) <<  "i" << endl;
			else
				return;
		}
	}

	//采用成员函数形式进行重载
	//返回值是引用
	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 + b

	a++;//后缀++的值是a变化之前的值
	++a;//前缀++的值是a变化之后的值

	Complex c1(1, -2);
	c1.print();
	Complex c2(5, -6);
	c2.print();

#if 0
	Complex c3 = c1 + c2;
	cout << "c1 + c2 = "; 
	c3.print();

	c1 += c2;
	c1.print();
#endif
	cout << 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;
			else
				cout << _dimag << "i" << endl;
		}
		else {
			cout << _dreal;
			if(_dimag > 0)
				cout << " + " << _dimag << "i" << endl;
			else if(_dimag < 0)
				cout << " - " << _dimag * (-1) <<  "i" << endl;
			else
				return;
		}
	}

	//采用成员函数形式进行重载
	//返回值是引用
	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;
		else
			os << 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 0
	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);
	friend bool operator>=(const String& lhs, const String& rhs);
#endif

	friend 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值