运算符重载
使对象的运算表现变得和编译器内置类型一样
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;
}