++运算符重载,--运算符重载
++运算符重载(前置++与后置++)
//++运算符重载
/*
当编译器看到++a(前置++),他就调用operator++(a),
当编译器看到a++(后置++),它就会调用operator++(a,int).
*/
#include <iostream>
using namespace std;
class Data
{
friend ostream& operator<<(ostream &out,Data &ob);
private:
int a;
int b;
public:
Data()
{
cout << "无参构造函数" << endl;
a = 0;
b = 0;
}
Data(int a, int b):a(a),b(b){
cout<<"有参构造"<<endl;
//this->a=a;
//this->b=b;
}
void showData(void){
cout<<"a = "<<a<<", b = "<<b<<endl;
}
~Data(){
cout<<"析构函数"<<endl;
}
//成员函数 重载前置++ ++ob1 (先加 后使用)
//编译器 默认识别 operator++(a)//但是a可以用this代替,
//从而化简operator++()
Data& operator++(){//++ob1
cout<<"前置++"<<endl;
//先加
a++;//a = this->a +1;
b++;//b = this->b +1;
//后使用
return *this;
}
//成员函数 重载后置++ ob1++ (先使用 后加)
//编译器 默认识别 operator++(a,int)//但是a可以用this代替,
//从而化简operator++(int)
Data operator++(int){//ob1++
//先使用(备份加之前的值)
Data old = *this;
//后加
a++;
b++;
return old;//因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
};
//普通全局函数 作为类的友元 重载>>运算符
ostream& operator<<(ostream &out,Data &ob){
cout<<"重载<<运算符:"<<"a = "<<ob.a<<", b = "<<ob.b<<endl;
return out;
}
void test01(){
Data ob1(10,20);
ob1.showData();
//重载<<直接输出自定义对象的值
cout<<ob1<<endl;
//成员函数 重载++运算符
cout<<++ob1<<endl;
Data ob2(10,20);
cout<< "ob2: " <<ob2<<endl;
Data ret = ob2++;
cout<<"ret = "<<ret<<endl;
cout<<ob2<<endl;
}
int main()
{
test01();
return 0;
}
有参构造
a = 10, b = 20
重载<<运算符:a = 10, b = 20
前置++
重载<<运算符:a = 11, b = 21
有参构造
ob2: 重载<<运算符:a = 10, b = 20
ret = 重载<<运算符:a = 10, b = 20
重载<<运算符:a = 11, b = 21
析构函数
析构函数
析构函数
–运算符重载(前置–与后置–)
//++运算符重载
/*
当编译器看到++a(前置++),他就调用operator++(a),
当编译器看到a++(后置++),它就会调用operator++(a,int).
*/
#include <iostream>
using namespace std;
class Data
{
friend ostream &operator<<(ostream &out, Data &ob);
private:
int a;
int b;
public:
Data()
{
cout << "无参构造函数" << endl;
a = 0;
b = 0;
}
Data(int a, int b) : a(a), b(b)
{
cout << "有参构造" << endl;
// this->a=a;
// this->b=b;
}
void showData(void)
{
cout << "a = " << a << ", b = " << b << endl;
}
~Data()
{
cout << "析构函数" << endl;
}
Data &operator--()
{ //--ob1
cout << "前置--" << endl;
//先减
a--; // a = this->a -1;
b--; // b = this->b -1;
//后使用
return *this;
}
Data operator--(int)
{ // ob1--
//先使用(备份加之前的值)
Data old = *this;
//后加
a--;
b--;
return old; //因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
};
//普通全局函数 作为类的友元 重载>>运算符
ostream &operator<<(ostream &out, Data &ob)
{
cout << "重载<<运算符:"
<< "a = " << ob.a << ", b = " << ob.b << endl;
return out;
}
void test01()
{
Data ob3(10, 20);
cout << "ob3:" << ob3 << endl;
cout << --ob3 << endl;
Data ob4(10, 20);
cout << "ob4:" << ob4 << endl;
Data ret = ob4--;
cout<<"ret"<<ret<<endl;
cout<<"ob4:"<<ob4<<endl;
}
int main()
{
test01();
return 0;
}
运行结果:
有参构造
ob3:重载<<运算符:a = 10, b = 20
前置--
重载<<运算符:a = 9, b = 19
有参构造
ob4:重载<<运算符:a = 10, b = 20
ret重载<<运算符:a = 10, b = 20
ob4:重载<<运算符:a = 9, b = 19
析构函数
析构函数
析构函数
后置++与后置- -的优化
原版:
Data operator++(int){//ob1++
//先使用(备份加之前的值)
Data old = *this;
//后加
a++;
b++;
return old;//因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
Data operator--(int){
// ob1--
//先使用(备份加之前的值)
Data old = *this;
//后加
a--;
b--;
return old; //因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
优化后:
因为, old变量是一个局部变量,所以不能用引用来接,
那么,这就造成在main主函数中,不能写成
cout<<ob1++<><endl;
必须要加入一个Date rate;变量来接ob1++;
要使,cout<<ob1++<><endl;成立,
则Data必须返回引用.
使得old不再是局部变量!
方法有:1.使得old变为static变量
2.使得old成为全局变量
Data& operator++(int){//ob1++
//先使用(备份加之前的值)
static Data old = *this;
//后加
a++;
b++;
return old;//因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
Data& operator--(int){
// ob1--
//先使用(备份加之前的值)
static Data old = *this;
//后加
a--;
b--;
return old; //因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
优化后后置++完整代码
//++运算符重载
/*
当编译器看到++a(前置++),他就调用operator++(a),
当编译器看到a++(后置++),它就会调用operator++(a,int).
*/
#include <iostream>
using namespace std;
class Data
{
friend ostream& operator<<(ostream &out,Data &ob);
private:
int a;
int b;
public:
Data()
{
cout << "无参构造函数" << endl;
a = 0;
b = 0;
}
Data(int a, int b):a(a),b(b){
cout<<"有参构造"<<endl;
//this->a=a;
//this->b=b;
}
void showData(void){
cout<<"a = "<<a<<", b = "<<b<<endl;
}
~Data(){
cout<<"析构函数"<<endl;
}
//成员函数 重载后置++ ob1++ (先使用 后加)
//编译器 默认识别 operator++(a,int)//但是a可以用this代替,
//从而化简operator++(int)
Data& operator++(int){//ob1++
//先使用(备份加之前的值)
static Data old = *this;
//后加
a++;
b++;
return old;//因为old是一个局部的值,所以返回值不能用 引用 ,而是直接返回Data
}
};
//普通全局函数 作为类的友元 重载>>运算符
ostream& operator<<(ostream &out,Data &ob){
cout<<"重载<<运算符:"<<"a = "<<ob.a<<", b = "<<ob.b<<endl;
return out;
}
void test01(){
Data ob2(10,20);
cout<< "ob2: " <<ob2<<endl;
cout<<"ob2++: "<< ob2++<<endl;
cout<< "ob2: " <<ob2<<endl;
}
int main()
{
test01();
return 0;
}
运行结果:
有参构造
ob2: 重载<<运算符:a = 10, b = 20
ob2++: 重载<<运算符:a = 10, b = 20
ob2: 重载<<运算符:a = 11, b = 21
析构函数
析构函数
补充一点:++x与x++那个是右值,哪个是左值
先说答案:
x++是右值,++x是左值.
x++是先把值取出来,存到一个临时变量里边,然后再给x加一,再把临时变量返回,
所以这个x的值是一个临时变量的值,是一个"将亡值",所以x++是一个右值.
++x是自增,然后把自己返回,自己是个x,不属于临时变量,所以++x是个左值
int* p = &x++;//编译失败,这个x是一个临时变量的值,是一个"将亡值",取不了地址
int* q = &++x;//编译成功
右值左值判断标准
标准一:
一般情况下,
临时变量是右值
标准二:
全部情况下,
不能取地址是右值
能取地址,也就是有地址的 是左值