程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++遞增(增量)運算符重載的思考

C++遞增(增量)運算符重載的思考

編輯:關於C++

在前面的章節中我們已經接觸過遞增運算符的重載,那時候我們並沒有區分前遞增與後遞增的差別,在通常情況下我們是分別不出++a與a++的差別的,但的確他們直接是存在明顯差別的。

先看如下代碼:

#include <iostream>
using namespace std;

int main()
{
int a=0;
++(++a);//正確,(++a)返回的是左值
(a++)++;//錯誤,(a++)返回的不是左值
system("pause");
}

代碼中(a++)++編譯出錯誤,返回“++”需要左值的錯誤,這正是前遞增與後遞增的差別導致的,那麼又是為什麼呢?

原因主要是由C++對遞增(增量)運算符的定義引發的。

他們之間的差別主要為以下兩點:

1、運算過程中,先將對象進行遞增修改,而後返回該對象(其實就是對象的引用)的叫前遞增(增量)運算。在運算符重載函數中采用返回對象引用的方式編寫。

2、運算過程中,先返回原有對象的值,而後進行對象遞增運算的叫後遞增(增量)運算。在運算符重載函數中采用值返回的方式編寫(這也正是前面(a++)++出錯誤的原因,(a++)返回的不是引用,不能當作左值繼續參加擴號外部的++運算),重載函數的內部實現必須創建一個用於臨時存儲原有對象值的對象,函數返回的時候就是返回該臨時對象。

那麼在編寫運算符重載函數的時候我們該如何區分前遞增運算符重載函數與後遞增運算符重載函數呢?

方法就是:在後遞增運算符重載函數的參數中多加如一個int標識,標記為後遞增運算符重載函數。

具體見如下實例(例一為非成員方式,例二為成員方式):

//例一 

//程序作者:管寧
//站點:www.cndev-lab.com
//所有稿件均有版權,如要轉載,請務必著名出處和作者
#include <iostream>
using namespace std;
class Test
{
public:
Test(int a=0)
{
Test::a = a;
}
friend Test& operator ++ (Test&);
friend Test operator ++ (Test&,int);
public:
int a;
};
Test& operator ++ (Test &temp)//前遞增
{
temp.a++;
return temp;
}
Test operator ++ (Test &temp,int)//後遞增,int在這裡只起到區分作用,事實上並沒有實際作用
{
Test rtemp(temp);//這裡會調用拷貝構造函數進行對象的復制工作
temp.a++;
return rtemp;
}
int main()
{
Test a(100);
++(++a);
cout<<a.a<<endl;
cout<<"觀察後遞增情況下臨時存儲對象的值狀態:"<<(a++).a<<endl;//這裡正是體現後遞增操作先返回原有對象值地方
cout<<a.a<<endl;
(a++)++;
cout<<a.a<<endl;//由於後遞增是值返回狀態,所以(a++)++只對a做了一次遞增操作,操作後為104而非105。
system("pause");
}

//例二 

//程序作者:管寧
//站點:www.cndev-lab.com
//所有稿件均有版權,如要轉載,請務必著名出處和作者
#include <iostream>
using namespace std;
class Test
{
public:
Test(int a=0)
{
Test::a = a;
}
Test& operator ++ ();
Test operator ++ (int);
public:
int a;
};
Test& Test::operator ++ ()//前遞增
{
this->a++;
return *this;
}
Test Test::operator ++ (int)//後遞增
{
Test rtemp(*this);//這裡會調用拷貝構造函數進行對象的復制工作
this->a++;
return rtemp;
}
int main()
{
Test a(100);
++(++a);
cout<<a.a<<endl;
cout<<"觀察後遞增情況下臨時存儲對象的值狀態:"<<(a++).a<<endl;//這裡正是體現後遞增操作先返回原有對象值地方
cout<<a.a<<endl;
(a++)++;
cout<<a.a<<endl;//由於後遞增是值返回狀態,所以(a++)++只對a做了一次遞增操作,操作後為104而非105。
system("pause");
}

通過對前後遞增運算的分析,我們可以進一步可以了解到,對於相同情況的單目運算符重載我們都必須做好這些區別工作,保證重載後的運算符符合要求。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved