# C++
[[___未完成]]
1.概念
运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能。这个函数叫做运算符重载函数(常为类的成员函数)。
用函数的方式实现了(+ - * / []数组 && || 逻辑 等)运算符的重载。根据需求决定重载那些运算符,用到的时候再百度案例即可。
2.运算符重载的基本格式
返回值类型 类名::operator重载的运算符(参数表)
{
……
}
operator是关键字,它与重载的运算符一起构成函数名。
3.运算符重载的两种方法
二元运算符重载
1.类内重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <iostream> using namespace std;
class Point{ public: Point(){}; Point (int x, int y): x(x),y(y) {}; Point operator+(const Point &b){ Point ret; ret.x = this->x + b.x; ret.y = this->y + b.y; return ret; } int x,y; };
int main() { Point a(2,4),b(5,3); Point c = a + b; cout<< "x :" << c.x << endl; cout<<"y :" << c.y << endl; }
|
运行结果:x : 7 y : 7
重点:运算符重载是类内重载时,运算符重载函数作为类的成员函数,以上述代码为例 a + b 相当于 a 对象调用+方法并且传入参数时 b 对象。
2.类外重载(用友元函数的方法实现)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <iostream> using namespace std;
class Point{ public: Point(){}; Point (int x, int y): x(x),y(y) {}; friend Point operator+(const Point &, const Point &); int x,y; };
Point operator+(const Point &a,const Point &b){ Point ret; ret.x = a.x + b.x; ret.y = a.y + b.y; return ret; }
int main() { Point a(2,4),b(5,3); Point c = a + b; cout<< "x :" << c.x << endl; cout<<"y :" << c.y << endl; }
|
一元运算符重载(注意:返回值当左值得时候,返回的是一个引用)
1.插入运算符重载>> and 提取运算符重载<<
以提取运算符重载<<为例,cout 是 ostream 类的对象。ostream 类和 cout 都是在头文件 中声明的。ostream 类将<<重载为成员函数。
下面我们重载 << 使用cout输出a对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <iostream> using namespace std;
class Point{ public: Point(){}; Point (int x, int y): x(x),y(y) {}; friend ostream &operator<<(ostream &out , const Point &a); private: int x,y; };
ostream &operator<<(ostream &out , const Point &a){ out << "<Point>( " << a.x << ", " << a.y << ")"; return out; }
int main() {
cout << c<< endl; }
|
输出结果:< Point>( 7, 7)
重点:另外应该会有人对ostream &operator<<(ostream &out , const Point &a)函数感到疑惑,首先在重载<<时,返回值类型是ostream&, 第一个参数也是ostream& 。也就是说,表达式cout<<c的返回值仍是 cout,所以cout<<c<<endl;才能成立。
2.前置运算符重载++ and 后置运算符重载++
重点:为区别前置和后置运算符,C++编译器要求,需要在后置运算符重载函数中加参数“int”,这个类型在此除了以示区别之外并不代表任何实际含义;如果不加,编译器无法区分是前置++,还是后置++,导致报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <iostream> using namespace std;
class Point{ public: Point(){}; Point (int x, int y): x(x),y(y) {}; friend Point operator+(const Point &, const Point &); friend ostream &operator<<(ostream &out , const Point &a); Point& operator++(){ this->x ++; this->y ++; return *this; } const Point operator++(int){ Point temp(x,y); this->x ++; this->y ++; return temp; } private: int x,y; };
Point operator+(const Point &a,const Point &b){ Point ret; ret.x = a.x + b.x; ret.y = a.y + b.y; return ret; }
ostream &operator<<(ostream &out , const Point &a){ out << "<Point>(" << a.x << " , " << a.y << ")"; return out; }
int main() { Point a(2,4),b(5,3); Point c = a + b; cout << c << endl; c++; cout << c << endl; ++c; cout << c << endl; }
|
3.=等号运算符重载
C++中,对类对象进行操作时,我们就不能只是简简单单地,对类对象用=进行操作。
当我们没有自己设计等号运算符的重载函数,编译器会自动生成一个浅拷贝的赋值运算符的重载函数。
浅拷贝:只是简单地将一个对象的内存数据赋值给另一个对象,如果这个对象成员变量引用了外部资源时(new),那么这两个对象的成员变量都指向这个空间,当这两个对象生存周期结束时,进行析构,那么就会崩溃,对同一块内存我们delete了两次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream> using namespace std;
class Name { public:
Name(const Name& obj) { m_len = obj.m_len; m_p = (char *)malloc(m_len + 1); strcpy(m_p, obj.m_p); }
Name& operator=(Name &obj) { if (this->m_p != NULL) { delete[] m_p; m_len = 0; } this->m_len = obj.m_len; this->m_p = new char [m_len+1]; strcpy(m_p, obj.m_p); return *this; } ~Name() { if (m_p != NULL) { free(m_p); m_p = NULL; m_len = 0; } } protected: private: char *m_p ; int m_len; };
void main() {
Name obj1("abcdefg"); Name obj2 = obj1; Name obj3("obj3");
obj1 = obj2 = obj3; cout<<"hello..."<<endl; system("pause"); return ; }
|
Reference
C++运算符重载(类内、外重载)_类外重载运算符++-CSDN博客