目录
- 运算符重载
- 加号运算符
- 左移运算符
- 递增运算符
- 赋值运算符
- 关系运算符
- 函数调用运算符
运算符重载
运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
加号运算符
目标:实现两个对象相加或类和其他数据类型相加
Animal dog(10);//实例对象
Animal cat(20);//实例对象
Animal pig1 = dog + cat;//对象+对象
Animal pig2 = dog + 10;//对象+整数
重写operator+实现加号运算符重载
有两种实现:成员函数实现和全局函数实现
class Animal{
pubilc:Animal(int a){this->a = a; }
//成员函数实现 + 号运算符重载Animal operator+(const Animal& p) {Animal temp;temp.a = this->a + p.a;//成员相加return temp;//返回临时对象}
pubilc:int a;//成员变量
}//全局函数实现 + 号运算符重载
//传参不一样,跟成员函数重载不冲突
Animal operator+(const Animal& p,int b){Animal temp;temp.a = p.a + b;//成员相加return temp;//返回临时对象
}int main(){Animal dog(10);//实例对象Animal cat(20);//实例对象Animal pig1 = dog + cat;//使用成员函数实现,相当于dog.operator+(cat)Animal pig2 = dog + 10;//使用全局函数实现,相当于operator+(dog,10);
}
左移运算符
目标:实现对象的<<链式编程
Animal dog();//实例对象
cout << dog << "hello world" << endl; //链式编程
重写operator<<实现左移运算符重载
成员函数无法实现预期的 << 号运算符重载效果,只能用全局函数实现
左移运算符需要一个左值和一个右值,如果使用成员函数实现,那就是:dog.operator<<(x),左值是对象,右值是传入参数,那么要使用这个重载,对象应写在左值位置,dog<<,这与我们想实现的cout << dog不符合
class Animal{pubilc:int a = 10;//成员变量int b = 20;//成员变量
}//全局函数实现 << 运算符重载
ostream& operator<<(ostream& out,Animal p){out << "a:" << p.a << " b:" << p.b;return out;//返回ostream类型,主要是考虑到链式编程连续<<的使用
}int mian(){Animal dog;//实例对象cout << dog << "hello world" << endl; //链式编程
}
递增运算符
目标:实现对象的++递增运算
Animal dog(10);//实例对象
dog++;
++dog;
重写operator++实现递增运算符重载
class Animal{
public:
//前置++Animal& operator++(){num++;//先++return *this;//再返回//返回引用,考虑到++(++a)的情况,应该递增同一个a对象 }
//后置++,使用传参int来区分于前置Animal operator++(int){Animal temp = *this; //记录当前本身的值num++;//再++return temp;//返回记录的值}
pubilc:int num = 10;//成员变量
}int mian(){Animal dog;//实例对象dog++;
}
赋值运算符
c++编译器默认会给类添加赋值运算符重载operator=, 对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
目标:实现对象的=号赋值运算
Animal p1(18);
Animal p2(20);
Animal p3(30);
p3 = p2 = p1; //赋值操作
重写operator=实现赋值运算符重载
class Animal{
pubilc:Animal(int a){m_Age = new int(a);//将数据开辟到堆区 }//重载赋值运算符Animal& operator=(Animal &p){if (m_Age != NULL){delete m_Age;m_Age = NULL;}//m_Age = p.m_Age; //编译器提供的代码是浅拷贝m_Age = new int(*p.m_Age);//提供深拷贝 解决浅拷贝的问题return *this; //返回自身}//有内存申请,应该写析构函数释放申请内存~Person(){if (m_Age != NULL){delete m_Age;m_Age = NULL;}}
public:int *m_Age;
}int mian(){Animal p1(18);Animal p2(20);Animal p3(30);p3 = p2 = p1; //赋值操作
}
关系运算符
目标:实现对象之间的关系运算
Animal dog(10);//实例对象
Animal cat(20);//实例对象
if(dog == cat){//对比两个实例
}
重写operator==实现关系运算符重载
class Animal{
pubilc:Animal(int a){this->a = a; }bool operator==(Animal& p){if (this->a == p.a){return true;}else{return false;}}
public:int a;
}int main(){Animal dog(10);//实例对象Animal cat(20);//实例对象if(dog == cat){cout << "dog和cat相等" << endl;}
}
函数调用运算符
函数调用运算符 () 也可以重载
由于重载后使用的方式非常像函数的调用,因此称为仿函数
仿函数没有固定写法,非常灵活
重写operator()实现函数调用运算符重载
例程:
class MyPrint
{
public:void operator()(string text){cout << text << endl;}
};
void test01()
{
//重载的()操作符 也称为仿函数MyPrint myFunc;myFunc("hello world");
}
class MyAdd
{
public:int operator()(int v1, int v2){return v1 + v2;}
};
void test02()
{
MyAdd add;
int ret = add(10, 10);
cout << "ret = " << ret << endl;
//匿名对象调用
cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;
}
int main() {test01();test02();
}