C++基础7 运算符重载

运算符重载

使对象的运算表现变得和编译器内置类型一样

a+b => a.operator+(b)

下面实现一下复数类的运算符重载

#include 
using namespace std;
class CComplex
{
public:
	CComplex(int r = 0, int i = 0)
		:mreal(r)
		,mimage(i)
	{}
	CComplex operator+(const CComplex& com)
	{
		/*CComplex comp;
		comp.mimage = this->mimage + com.mimage;
		comp.mreal = this->mreal + com.mreal;*/
		return CComplex(this->mreal + com.mreal,this->mimage + com.mimage);
	}
	CComplex operator++(int)
	{
		/*CComplex comp = *this;
		this->mimage += 1;
		this->mreal += 1;
		return comp;*/
		return CComplex(this->mreal++, this->mimage++);
	}
	CComplex& operator++()
	{
		this->mimage += 1;
		this->mreal += 1;
		return *this;
	}
	void operator+=(const CComplex& rhs)
	{
		this->mreal += rhs.mreal;
		this->mimage += rhs.mimage;
	}
	void show()
	{
		cout << "mreal:" << this->mreal
			<< "  " << "mimage;" << this->mimage << endl;
	}
private:
	int mreal;
	int mimage;
	//友元函数
	friend CComplex operator+(const CComplex& rhs1, const CComplex& rhs2);
	friend ostream& operator<<(ostream& out, const CComplex& rhs);
	friend istream& operator>>(istream& in, CComplex& rhs);
};
CComplex operator+(const CComplex& rhs1, const CComplex& rhs2)
{
	return CComplex(rhs1.mreal + rhs2.mreal, rhs1.mimage + rhs2.mimage);
}
ostream& operator<<(ostream& out, const CComplex& rhs)
{
	out << "mreal: " << rhs.mreal << " " << "mimage: " << rhs.mimage << endl;
	return out;
}
istream& operator>>(istream& in, CComplex& rhs)
{
	in >> rhs.mreal >> rhs.mimage;
	return in;
}
int main()
{
	CComplex c1(10, 10);
	CComplex c2(20, 20);
	CComplex c3 = c1 + c2;
	c3.show();
	CComplex c4 = c2 + 20;
	c4.show();
	//编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法
	//就在全局作用域找合适的运算符重载
	CComplex c5 = 20 + c2; //调用全局加法运算符重载
	c5.show();
	c5 = c1++; // ++单目运算符 operator()前置加加 operator(int)后置加加
	c1.show();
	c5.show();
	c5 = ++c1;
	c1.show();
	c5.show();
	c1 += c2;
	c1.show();
	//输出运算符重载提供全局方法
	cout << c1 << c2 << endl; 
	cin >> c1;
	cout << c1;
	return 0;
}

自定义string的运算符重载

#include 
using namespace std;
class String
{
public:
	String(const char* p = nullptr)
	{
		if (p != nullptr)
		{
			str = new char[strlen(p) + 1];
			strcpy(str, p);
		}
		else
		{
			str = new char[1];
			*str = '\0';
		}
	}
	~String()
	{
		delete []str;
		str = nullptr;
	}
	String(const String& rhs)
	{
		this->str = new char[strlen(rhs.str) + 1];
		strcpy(this->str, rhs.str);
	}
	String& operator=(const String & rhs)
	{
		if (this == &rhs)
		{
			return *this;
		}
		delete []str;
		str = new char[strlen(rhs.str) + 1];
		strcpy(str, rhs.str);
		return *this;
	}
	bool operator>(const String& rhs) const
	{
		return strcmp(str, rhs.str) > 0;
	}
	bool operator<(const String& rhs) const
	{
		return strcmp(str, rhs.str) < 0;
	}
	bool operator==(const String& rhs) const
	{
		return strcmp(str, rhs.str) == 0;
	}
	int length()const
	{
		return strlen(str);
	}
	char& operator[](int index)
	{
		return str[index];
	}
	const char& operator[](int index) const
	{
		return str[index];
	}
	const char* c_str() const
	{
		return str;
	}
private:
	char* str;
	friend ostream& operator<<(ostream& out, const String& rhs);
	friend String operator+(const String& rhs1, const String& rhs2);
};
String operator+(const String& rhs1, const String& rhs2)
{
	//char* temp = new char[strlen(rhs1.str) + strlen(rhs2.str) + 1];
	String tem;
	tem.str = new char[strlen(rhs1.str) + strlen(rhs2.str) + 1];
	strcpy(tem.str, rhs1.str);
	strcat(tem.str, rhs2.str);
	return tem;
}
ostream& operator<<(ostream& out, const String& rhs)
{
	out << rhs.str;
	return out;
}
int main()
{
	String s1("aaa");
	String s2("bbb");
	String s3 = s1 + s2;
	cout << s1;
	cout << s3;
	return 0;
}

容器迭代器

迭代器可以透明的访问容器内部的元素的值

string s1 = "hello world"
string::iterator it = s1.being();
for(;it!=s1.end();++s1)
{
    cout << *it << " ";
}
#include 
using namespace std;
class String
{
public:
	String(const char* p = nullptr)
	{
		if (p != nullptr)
		{
			str = new char[strlen(p) + 1];
			strcpy(str, p);
		}
		else
		{
			str = new char[1];
			*str = '\0';
		}
	}
	~String()
	{
		delete []str;
		str = nullptr;
	}
	String(const String& rhs)
	{
		this->str = new char[strlen(rhs.str) + 1];
		strcpy(this->str, rhs.str);
	}
	String& operator=(const String & rhs)
	{
		if (this == &rhs)
		{
			return *this;
		}
		delete []str;
		str = new char[strlen(rhs.str) + 1];
		strcpy(str, rhs.str);
		return *this;
	}
	bool operator>(const String& rhs) const
	{
		return strcmp(str, rhs.str) > 0;
	}
	bool operator<(const String& rhs) const
	{
		return strcmp(str, rhs.str) < 0;
	}
	bool operator==(const String& rhs) const
	{
		return strcmp(str, rhs.str) == 0;
	}
	int length()const
	{
		return strlen(str);
	}
	char& operator[](int index)
	{
		return str[index];
	}
	const char& operator[](int index) const
	{
		return str[index];
	}
	const char* c_str() const
	{
		return str;
	}
	class iterator
	{
	public:
		iterator(char* p = nullptr)
			:_p(p)
		{

		}
		bool operator!=(const iterator& it)
		{
			return _p != it._p;
		}
		void operator++()
		{
			++_p;
		}
		char& operator*()
		{
			return *_p;
		}
	private:
		char* _p;
	};
	iterator begin()
	{
		return iterator(str);
	}
	iterator end()
	{
		return iterator(str + length());
	}
private:
	char* str;
	friend ostream& operator<<(ostream& out, const String& rhs);
	friend String operator+(const String& rhs1, const String& rhs2);
};
String operator+(const String& rhs1, const String& rhs2)
{
	//char* temp = new char[strlen(rhs1.str) + strlen(rhs2.str) + 1];
	String tem;
	tem.str = new char[strlen(rhs1.str) + strlen(rhs2.str) + 1];
	strcpy(tem.str, rhs1.str);
	strcat(tem.str, rhs2.str);
	return tem;
}
ostream& operator<<(ostream& out, const String& rhs)
{
	out << rhs.str;
	return out;
}
int main()
{
	String s1("aaa");
	String::iterator it = s1.begin();
	for (; it != s1.end(); ++it)
	{
		cout << *it << " ";
 	}
	cout << endl;
	return 0;
}

下面对自定义的vector容器实现迭代器

#include 
using namespace std;
template
class vector
{
public:
	vector(int size = 10)
		:_first(new T[size])
		, _last(_first)
		, _end(_first + size)
	{

	}
	~vector()
	{
		delete[]_first;
		_first = _last = _end = nullptr;
	}
	vector(const vector& other)
	{
		_first = new T[other._end - other._first];
		for (int i = 0; i < (other._last - other._first); i++)
		{
			_first[i] = other._first[i];
		}
		_last = _first + other._last - other._first;
		_end = _first + other._end - other._first;
	}
	vector& operator=(const vector& other)
	{
		if (this == &other)
		{
			return *this;
		}
		delete[]_first;
		_first = new T[other._end - other._first];
		for (int i = 0; i < (other._last - other._first); i++)
		{
			_first[i] = other._first[i];
		}
		_last = _first + other._last - other._first;
		_end = _first + other._end - other._first;
		return *this;
	}
	void push_back(T val)
	{
		if (full())
		{
			expand();
		}
		*_last++ = val;
	}
	void pop_back()
	{
		if (empty())
		{
			return;
		}
		--_last;
	}
	T back() const
	{
		if (empty())
		{
			throw "vector is empty";
		}
		return *(_last - 1);
	}
	bool full() const
	{
		return _last == _end;
	}
	bool empty() const
	{
		return _first == _last;
	}
	int size() const
	{
		return _last - _first;
	}
	T& operator[](int index)
	{
		if (index < 0 || index >= size())
		{
			throw "";
		}
		return _first[index];
	}
	class iterator
	{
	public:
		iterator(T* p = nullptr)
			:ptr(p)
		{

		}
		bool operator!=(const iterator & rhs)
		{
			return ptr != rhs.ptr;
		}
		void operator++()
		{
			++ptr;
		}
		T& operator*()
		{
			return *ptr;
		}
		const T& operator*() const
		{
			return *ptr;
		}
	private:
		T* ptr;
	};
	iterator begin()
	{
		return iterator(_first);
	}
	iterator end()
	{
		return iterator(_last);
	}
private:
	T* _first;
	T* _last;
	T* _end;
	void expand()
	{
		int size = _end - _first;
		T* temp = new T[2 * size];
		for (int i = 0; i < size; i++)
		{
			temp[i] = _first[i];
		}
		delete[]_first;
		_first = temp;
		_end = _first + size * 2;
		_last = _first + size;
	}
};
int main()
{
	vector vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100);
	}
	cout << vec[5] << endl;
	vector::iterator it = vec.begin();
	for (; it != vec.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
	cout << endl;
	return 0;
}

迭代器失效问题

迭代器失效的问题,下面代码第一次调用erase以后,删除点之后的迭代器it就失效了

#include 
#include 
using namespace std;
int main()
{
	vector v1;
	for (int i = 0; i < 20; ++i)
	{
		v1.push_back(rand() % 100);
	}
	vector::iterator it = v1.begin();
	for (; it != v1.end(); ++it)
	{
		if (*it % 2 == 0)
		{
			v1.erase(it);
		}
	}
	return 0;
}

下面代码,迭代器在第一次insert之后,当容器没有扩容时,增加元素后的iterator就失效了,但当容器扩容后迭代器就全部失效了

#include 
#include 
using namespace std;
int main()
{
	vector v1;
	for (int i = 0; i < 20; ++i)
	{
		v1.push_back(rand() % 100);
	}
	vector::iterator it = v1.begin();
	for (; it != v1.end(); ++it)
	{
		/*if (*it % 2 == 0)
		{
			v1.erase(it);
		}*/
		if (*it % 2 == 0)
		{
			v1.insert(it, *it - 1);
		}
	}
	return 0;
}

对插入和删除点的迭代器进行更新操作就可以避免迭代器失效

#include 
#include 
using namespace std;
int main()
{
	vector v1;
	for (int i = 0; i < 20; ++i)
	{
		v1.push_back(rand() % 100);
	}
	vector::iterator it = v1.begin();
	for (; it != v1.end(); )
	{
		if (*it % 2 == 0)
		{
			it = v1.erase(it);
		}
		else
		{
			++it;
		}
		/*if (*it % 2 == 0)
		{
			v1.insert(it, *it - 1);
		}*/
	}
	return 0;
}
#include 
#include 
using namespace std;
int main()
{
	vector v1;
	for (int i = 0; i < 20; ++i)
	{
		v1.push_back(rand() % 100);
	}
	for (int val : v1)
	{
		cout << val << " ";
	}
	cout << endl;
	vector::iterator it = v1.begin();
	for (; it != v1.end(); ++it)
	{
		/*if (*it % 2 == 0)
		{
			it = v1.erase(it);
		}
		else
		{
			++it;
		}*/
		if (*it % 2 == 0)
		{
			it = v1.insert(it, *it - 1);
			++it;
		}
	}
	for (int val : v1)
	{
		cout << val << " ";
	}
	cout << endl;
	return 0;
}

你可能感兴趣的:(C++基础,c++,开发语言)