前提知识:
前置++,可以进行多次++操作,而后置++,无法进行多次++操作。
int a = 10;
int b = 10;
cout<<++(++a)<<endl;//正常运行
cout<<(b++)++<<endl;//错误,表达式必须是可修改的左值
错误原因,在于后置++一次,返回的是常量,不是变量。
int b = 10;
cout<<b++<<endl;// b = 10
cout<<b<<endl; // b = 11
前置++是先自加再使用,而后置++是先使用再自加
说明后置++的原理是先创建一个临时变量来保存当前的值,再返回这个临时变量的值。那么,返回的就不再是对象变量本身,而是一个临时变量的值,且没有地址(临时变量内存位于栈区,生命周期在函数体内,执行完函数就会销毁),所以是一个常量。
++运算符重载
创建MyInt类,成员变量属性设为私有。
class MyInt
{ //友元函数
friend ostream& operator<<(ostream& cout, MyInt myint);
public:
MyInt()
{
this->m_Num = 0;
}
private:
int m_Num;
};
前提:需要先重载<<运算符。(<<运算符的重载只能是全局函数)
//重载<<运算符
ostream& operator<<(ostream& cout, MyInt myint)
{
cout<< myint.m_Num;
return cout;
}
因为类成员变量属性为私有,所以我们使用友元函数在重载的<<运算符函数中进行访问私有变量。
对重载<<运算符的解释:
链式编程思想:流操作符<<和>>在I/O流中就是使用链式调用的方式,使得我们可以在一个语句中连续地对输入或输出进行多个操作。(强调同一个对象)
所以我们需要对第一个形参 输出流对象形参进行引用,返回类型也需要进行引用返回,这样才能持续输出<<1<<endl(即多次使用<<),保证是同一个对象在输出。第二个形参则不要求引用,因为仅仅只是输出对象myint的值,并不涉及输出地址。(但规范,还是引用较好,为了强调返回的是同一个对象,值传递会进行拷贝对象,也不会影响对象本身。这里是为了适应重载后置++运算符的条件才设计第二个形参不进行引用)
即:在重载<<运算符中,重载前置++运算符时,第二个形参可以进行引用。重载后置++运算符时,第二个形参则不允许使用形参。
1、重载前置++:
class MyInt
{ //友元函数
friend ostream& operator<<(ostream& cout, MyInt myint);
public:
MyInt()
{
this->m_Num = 0;
}
//前置++ 返回引用为了一直对一个数据进行递增操作
MyInt& operator++()
{
this->m_Num++;//m_Num + 1
return *this;//返回对象本身
}
private:
int m_Num;
};
注意:因为前置++是先自加再使用,所以返回的是对象本身,那么我们可以使用引用方式来返回对象本身。(即可以++(++myint))
在cout输出时,重载的左移运算符函数ostream& operator<<(ostream& cout, MyInt myint)中的第二个形参是可以改成&MyInt myint的。
void test01()
{
MyInt myint;
cout << "前置++:" << endl;
cout << ++(++myint) << endl;
cout << myint << endl;
}
运行结果:
2、重载后置++:
class MyInt
{ //友元函数
friend ostream& operator<<(ostream& cout, MyInt myint);
public:
MyInt()
{
this->m_Num = 0;
}
//后置++
MyInt operator++(int)
{
MyInt temp = *this;
this->m_Num++;//m_Num + 1
return temp;//返回临时变量temp
}
private:
int m_Num;
};
注意:因为后置++是先使用再自加,所以返回的是临时变量的值,临时变量会在函数执行完时销毁,所以返回的是没有了地址的常量。(引用无法对临时变量进行返回,引用的本身是指针常量,指向的对象需要含有地址)(即不可以(myint++)++)
在cout输出时,重载的左移运算符函数ostream& operator<<(ostream& cout, MyInt myint)中的第二个形参不可以改成&MyInt myint,因为返回的不是对象本身。
void test02()
{
MyInt myint;
cout << "后置++:" << endl;
cout << (myint++)++ << endl;
cout << myint << endl;
}
运行结果:
--运算符重载
--运算符重载跟++运算符重载是一样的原理。
前置--,可以进行多次--操作,而后置--,无法进行多次--操作。
重载前置--:
class MyInt
{ //友元函数
friend ostream& operator<<(ostream& cout, MyInt myint);
public:
MyInt()
{
this->m_Num = 0;
}
//前置--
MyInt& operator--()
{
this->m_Num--;//m_Num - 1
return *this;//返回对象本身
}
private:
int m_Num;
};
void test03()
{
MyInt myint;
cout << "前置--:" << endl;
cout << --(--myint) << endl;
cout << myint << endl;
}
运行结果:
重载后置--:
class MyInt
{ //友元函数
friend ostream& operator<<(ostream& cout, MyInt myint);
public:
MyInt()
{
this->m_Num = 0;
}
//后置--
MyInt operator--(int)
{
MyInt temp = *this;
this->m_Num--;
return temp;
}
private:
int m_Num;
};
void test04()
{
MyInt myint;
cout << "后置--:" << endl;
cout << (myint--)-- << endl;
cout << myint << endl;
}
运行结果: