运算符重载分为两种形式,一种是成员函数重载,一种是全局函数重载。
- +重载
采用成员和全局重载的方法是相同的结果的,但是请注意全局重载有两个参数第一个参数是加号左边的值,第二个参数是加号右边的值;而对于成员函数重载只有一个参数,加号左边的对象是重载函数的调用者,加号右边 的对象作为参数传入重载函数
- <<重载
需要认识到的是,ostream类中,cout对象是单例的,它没有拷贝函数,这就要求对<<重载函数的返回值类型必须是 ostream &。另外,由于cout是左值,调用的对象是右值,所以重载函数必须是全局重载,因为不能是
object << cout。
- ++重载
这包含两种重载类型,一种是前置重载,一种是后置重载。前置递增没有参数,后置递增包含参数。
1.前置重载
在讨论前置递增之前,我们首先研究引用返回和值返回的区别。
此处有一个类Dog,若有一个函数返回值是Dog,我们成为是值返回;如果返回值是Dog &,我们称这种返回叫做引用返回。值返回会产生一个临时变量,return的过程就是使用拷贝函数对临时对象赋值的过程,值 得注意的是,临时对象的生命周期比函数内部的局部变量的生命周期更长;而引用返回则不同,return 的过程中不产生临时变量,这样不仅减少了内存资源的消耗,而且便于使返回值作为左值参与运算。
有了上面的分析,我们知道了,对于对此的递增运算,如++(++dog),其中 dog 是Dog类的一个对象,如果采用值返回,在进行了一次运算后,返回的是临时对象,这样dog本身不会在自增,基于此,我们可以得
出自增运算符重载的函数返回值必须是引用类型。
2.后置重载
后置递增与前置递增不同,后置递增首先返回该对象的值,再将对象自增。
后置递增的声明:Dog operator++(int),注意后置自增的展位参数必须是 int 类型。
后置递增返回类型必须是值返回,因为下面的代码中,tmp 是局部变量,再执行完自增后,函数中定义的局部变量就会被销毁,这个时候对该对象的访问时非法的。
#include <iostream> #include <string> using namespace std; class Dog { private: string name; int age; public: Dog(string name, int age) { this->name = name; this->age = age; } Dog operator+(Dog& d); Dog& operator++(); Dog operator++(int); string getName() const { return name; } int getAge() { return age; } Dog setAge(int age) { this->age = age; return *this; } void show() { cout << name << '\t' << age << endl; } }; //加号成员函数重载 Dog Dog::operator+(Dog& d) { this->age += d.age; return*this; } //加号全局函数重载 Dog operator+(const Dog& d, int x) { Dog tmp(d.getName(), 10); return tmp.setAge(tmp.getAge() + x); } //左移运算符重载 ostream& operator<<(ostream& cout, Dog d) { cout << d.getName() << '\t' << d.getAge(); return cout; } //前置递增,返回类型必须是引用返回 Dog& Dog::operator++() { age++; return *this; } //后置递增,返回类型必须是值返回 Dog Dog::operator++(int) { Dog tmp = *this; age++; return tmp; } int main() { Dog d1("eta", 0); Dog d2("vii", 1); cout << "d1 ++ : " << ++(++d1) << endl; d1 = d1 + d2; d1.show(); d2.show(); d2 = d2 + 10; d2.show(); cout << d2 << endl; cout << d2++ << endl; cout << d2 << endl; return 0; }
标签:return,函数,int,age,Dog,运算符,重载 From: https://www.cnblogs.com/meetalone/p/17153568.html