后置
当定义后置++的时候,发现,与前置++使用的是一样的名字,发现了重定义,那这个时候怎么办?可以在参数中写一个int,用于区分,这个int属于占位参数,用于区分前置递增和后置递增,编译器是只认int的,对于后置递增,应该记录初始结果,如果在递增,返回初始结果,这个时候应该返回值,而不是引用,因为返回的是一个局部变量,如果返回引用,就会非法访问:
不是用引用
#include<iostream> using namespace std; class A { public: A(int a) { _a = a; } //后置++ A operator++(int) { int a = this->_a++; return a; } int _a; }; void test1() { A a1(10); cout << a1._a++ << endl; cout << a1._a << endl; } int main() { test1(); return 0; }
是引用
#include<iostream> using namespace std; class A { public: A(int a) { _a = a; } //后置++ A& operator++(int) { int a = this->_a++; return a; } int _a; }; void test1() { A a1(10); cout << a1._a++ << endl; cout << a1._a << endl; } int main() { test1(); return 0; }
赋值运算符重载
其实在C++中,编译器一般会给一个类默认提供四个函数
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝函数,对属性进行浅拷贝
4.赋值运算符,对属性进行浅拷贝
注意!:
当这个时候属性内的值有属性指向堆区时,赋值操作符也会产生深拷贝和浅拷贝问题
编译器提供的是浅拷贝,这个时候在析构函数内进行delete释放内存时,会出现内存释放两次,所以这个时候operator=修改成深拷贝即可,注意,在赋值操作符之前,应该先判断赋值左侧值内堆区是否有数据,有数据要先释放干净,在进行深拷贝,记得返回值要返回自身:
#include<iostream> using namespace std; class A { public: A() { p = new int; } ~A() { delete p; p = NULL; } void operator=(A& a) { if (p != NULL) { p = NULL; } p = new int(*a.p); } int* p; }; void test1() { A a; *a.p = 10; A b; b = a; cout << *b.p << endl; } int main() { test1(); return 0; }
关系运算符重载
作用
可以人两个自定义类型进行比较操作
实现
只用对比每一组属性是否相等,相等返回真,不相等返回假:
#include<iostream> using namespace std; class A { public: A(int a, char c) { _a = a; _c = c; } bool operator==(A& a) { if (_a == a._a && _c == a._c) { return 1; } return 0; } int _a; char _c; }; void test1() { A a(10, 'c'); A b(10, 'c'); if (a == b) { cout << "a=b" << endl; } else { cout << "a!=b" << endl; } } int main() { test1(); return 0; }
函数调用运算符重载
函数调用操作符()也可以重载
由于重载后调用的方式和函数本身的调用相似,所以也被称为仿函数
仿函数没有固定写法,函数体内可以写任何。
事例:
#include<iostream> using namespace std; class A { public: void operator()() { cout << "仿函数调用" << endl; } }; void test1() { A a; a(); } int main() { test1(); return 0; }
第二种重载掌握!突破
面前的石碑碎去,露出后面黑黝黝的洞口…
本章知识点(图片形式)