目录
概念:
运算符重载与函数重载比较类似,相当于让一个运算符具有另外一种含义;
语法:
定义重载的运算符就像定义函数,只是该函数的名字是 operator@,这里的@代表了被重载的运算符。函数的参数中参数个数取决于两个因素。运算符是一元(一个参数)的还是二元(两个参数);运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对于一元没有参数,对于二元是一个参数-此时该类的对象用作左耳参数)
- #include
-
- using namespace std;
-
- class person
- {
- public:
- person(int age)
- {
- this->age = age;
- }
- person operator+(person &p2)//
- {
- person p = (this->age+p2.age);
- return p;
- }
- int age;
- };
- void test01()
- {
- person p1(10);
- person p2(20);
- person p3 = p1 + p2;
- cout << p3.age << endl;
-
- }
- int main()
- {
- test01();
- return 0;
- }
-
-
- #include
-
- using namespace std;
-
- class person
- {
- public:
- person(int age)
- {
- this->age = age;
- }
-
- int age;
- };
-
- person operator+(person &p1,person &p2)//
- {
- person p = (p1.age+p2.age);
- return p;
- }
-
- void test01()
- {
- person p1(10);
- person p2(20);
- person p3 = p1 + p2;
- cout << p3.age << endl;
-
- }
- int main()
- {
- test01();
- return 0;
- }
将左移运算符的重载函数声明为类的友元函数 就可以访问类的成员
- #include
-
- using namespace std;
-
- class person
- {
- friend ostream & operator<<(ostream &cout,person &p);
- public:
- person(int age)
- {
- this->age = age;
- }
- private:
- int age;
- };
-
- ostream & operator<<(ostream &cout,person &p)
- {
- cout << p.age;
- return cout;
- }
-
- void test01()
- {
- person p1(10);
- cout << p1 << endl;
-
- }
- int main()
- {
- test01();
- return 0;
- }


a++是先把a赋值到一个临时空间,再对a+1赋值给临时变量,等运算结束后才返回临时变量给a (参与运算的是自加之前的值)
++a是先给a+1,直接对a赋值,不需要开辟临时空间(参与运算的是返回值的引用)
前置++返回的是引用
后置++返回的是对象
前置++调用void operator++()
后置++调用myint operator++(int) 后置++多了一个占位参数
- #include
-
- using namespace std;
-
- class myint
- {
- public:
- myint &operator++()
- {
- this->num = this->num+1;
- return *this;
- }
- myint(int num)
- {
- this->num = num;
- }
- myint operator++(int)
- {
- myint tmp = *this;
-
- this->num = this->num+1;
- return tmp;
- }
-
- int num;
- };
-
- ostream &operator<<(ostream& cout,myint &p)
- {
- cout << p.num;
- return cout;
- }#include
-
- using namespace std;
-
- class myint
- {
- public:
- myint &operator++()
- {
- this->num = this->num+1;
- return *this;
- }
- myint(int num)
- {
- this->num = num;
- }
- myint operator++(int)
- {
- myint tmp = *this;
-
- this->num = this->num+1;
- return tmp;
- }
-
- int num;
- };
-
- ostream &operator<<(ostream& cout,myint &p)
- {
- cout << p.num;
- return cout;
- }
-
- void test01()
- {
- myint p1(10);
- cout << p1 << endl;
- ++p1;//调用operator++(p1)或者p1.operator()
- cout << ++p1 << endl;
- p1++;
- //cout << p1++ << end; //有些编译器会报错
- cout << p1 << endl;
- }
- int main()
- {
- test01();
- return 0;
- }
我们经常new出一个对象,忘记释放,所以我们使用智能指针来维护
智能指针实质上是一个局部对象 这个局部对象维护了new出来的对象的地址,在局部对象的析构函数中,会帮忙释放new出来的对象
对于智能指针我们重载了->和* 让智能指针和普通指针一样使用
- #include
-
- using namespace std;
-
- class person
- {
- public:
-
- person(int age )
- {
- this->age = age;
- }
- int age;
- };
-
- class SmartPointer
- {
- public:
- SmartPointer(person *p1)
- {
- this->p = p1;
- }
- ~SmartPointer()
- {
- delete p;
- cout << "释放了p" << endl;
- }
- person *p;
- };
-
- void test01()
- {
- //局部对象 在释放之前可以帮助释放p
- person *p = new person(10);
- SmartPointer s1(p);
- cout << p->age <
- cout <<
- }
- int main()
- {
- test01();
- return 0;
- }
重载等号运算符(=)
编译器默认给每个类加上了四个函数
默认的无参构造
默认的拷贝构造
析构函数
operator=()
- #include
- #include
-
- using namespace std;
-
- class person
- {
- public:
- person()
- {
-
- }
-
- person(int agel,char *namel)
- {
- age = agel;
- name = new char[strlen(namel)+1];
- strcpy(name,namel);
- }
-
- person& operator=(person &p1)
- {
- this->age = p1.age;
- this->name = new char[strlen(p1.name)+1];
- strcpy(this->name,p1.name);
-
- return *this;//返回p2 为什么不返回p1?可以连续赋值 p3 = p2 = p1
- }
-
- ~person()
- {
- delete []name;
- }
- int age;
- char *name;
- };
-
- void test01()
- {
- person p1(10,(char *)"bob");
- person p2;
- p2 = p1;//p2.operator(person &p1)
- cout << p2.age << " " << p2.name <
- }
-
- int main()
- {
- test01();
- return 0;
- }
重载等于和不等运算符(== !=)
- #include
- #include
-
- using namespace std;
-
- class person
- {
- public:
- person()
- {
-
- }
- bool operator==(person &p2)
- {
- return this->age == p2.age && this->name == p2.name;
- }
- bool operator!=(person &p2)
- {
- return this->age != p2.age || this->name != p2.name;
- }
- person(int age,string name)
- {
- this->age = age;
- this->name = name;
- }
- int age;
- string name;
- };
-
- void test01()
- {
- person p1(10,"lucy");
- person p2(10,"bob");
- if(p1 == p2)
- {
- cout << "p1 = p2" << endl;
- }
- if(p1 != p2)
- {
- cout << "p1 != p2" << endl;
- }
- }
-
- int main()
- {
- test01();
- return 0;
- }
函数调用符号()重载
一个类中重载了()的类,那么类的定义出来的对象可以像函数一样使用,本质是调用了operator()这个函数
- #include
- #include
-
- using namespace std;
-
- class Myadd
- {
- public:
- int add(int a,int b)
- {
- return a + b;
- }
- int operator()(int x,int y)
- {
- return x + y;
- }
- };
-
- void test01()
- {
- Myadd p;
- cout << p.add(3,5) << endl;
- //p() 可以像函数一样调用的对象 函数对象
- cout << p(3,4) << endl;//p.operator()(3,4)
- cout << Myadd()(3,4) << endl;//定义一个匿名对象 Myadd().operator()(3,4)
- }
-
- int main()
- {
- test01();
- return 0;
- }
-
-
尽量不要重载 || &&
不能重载
operator&&
和
operator||
的原因是,无法在这两种情况下实现内置操作符的完整语义。说得更具体一 些,内置版本版本特殊之处在于:内置版本的&&
和
||
首先计算左边的表达式,如果这完全能够决定结果,就无需计算右边的表达式了--
而且能够保证不需要。我们都已经习惯这种方便的特性了。 我们说操作符重载其实是另一种形式的函数调用而已,对于函数调用总是在函数执行之前对所有参数进行求值。
class
Complex{
public
:
Complex(
int
flag)
{
this
->flag = flag;
}
Complex&
operator
+=(Complex& complex)
{
this
->flag =
this
->flag + complex.flag;
return
*
this
;
}
bool
operator
&&(Complex& complex)
{
return this
->flag && complex.flag;
}
public
:
int
flag;
};
int
main(){
Complex complex1(
0
);
//flag 0
Complex complex2(
1
);
//flag 1
//原来情况,应该从左往右运算,左边为假,则退出运算,结果为假
//这边却是,先运算(
complex1+complex2
),导致,
complex1
的
flag 变为 complex1+complex2
的值,complex1.a = 1
// 1 && 1
//complex1.operator&&(complex1.operator+=(complex2))
if
(complex1 && (complex1 += complex2))
{
//complex1.operator+=(complex2)
cout <<
"
真
!"
<< endl;
}
else
{
cout <<
"
假
!"
<< endl;
}
return
EXIT_SUCCESS;
}
符号重载总结
1.=, [], ()
和
->
操作符只能通过成员函数进行重载
例如 :p = 3 成员函数实现 p.operator=(3) 全局函数实现 operator(3,p) 如果把3写在左边 相当于 3 = p,将p赋值给3,但3是一个常量,常量不能作为左值
2.<<
和
>>
只能通过全局函数配合友元函数进行重载
例如:cout << p 因为要把cout放在操作符的左侧 不可能去修改标准库中的类 所以必须配合全局函数和友元函数进行重载
3.不要重载
&&
和
||
操作符,因为无法实现短路规则
内置版本的&&
和
||
首先计算左边的表达式
常规建议
-
相关阅读:
以用户需求为核心能玩出什么新花样?魅族 19 主理人计划构建理想机型
NLP之TextLSTM(预测单词下一个字母)
微信小程序将后端返回的图片文件流解析显示到页面
SQL学习记录
想要精通算法和SQL的成长之路 - 划分字母区间
如何在用pip配置文件设置HTTP爬虫IP
高斯金字塔的秘密(二,加速高斯,c#实现)
Docker文档阅读笔记-How to Commit Changes to a Docker Image with Examples
仿东郊到家小程序源码 同城按摩源码 家政小程序源码 美容理疗小程序源码+公众号H5+APP源码
uniapp上echarts地图钻取
-
原文地址:https://blog.csdn.net/2301_77164542/article/details/132852744