不知道你是否聽說過++i比i++快的說法,真的如此嗎?
這兩個表示式從我們初學程式語言的時候就會接觸到。前者是自增後取值,後者是取值後自增。
我們看乙個簡單的例子。
#include using namespace std;
int main()
編譯後報錯:
main.cpp:7:19: error: lvalue required as unary 『&』 operand
int *c = &(a++);
說&作用於左值,也就是說a++的結果並非左值。但++b的結果是。
可簡單理解左值和右值:
在《運算子過載》一文中已經說到了運算子的過載,通過前面的例子也發現了,對於內建型別,前置自增返回物件的引用,而後置自增返回物件的原值(但非左值)。
基於上述原則,乙個前置版本和後置版本的常見實現如下:
class test
;/*前置自增實現正規化*/
test& test::operator++()
/*後置自增實現正規化,為了與前置區分開,多了乙個int引數,但從來沒用過*/
const test test::operator++(int)
仔細觀察後,我們發現前置自增,先自增,後返回原物件的物件;沒有產生任何臨時物件;而後置自增,先儲存原物件,然後自增,最後返回該原臨時物件,那麼它就需要建立和銷毀,這樣一來,效率孰高孰低就很清楚了。
在不進行賦值的情況下,內建型別前置和後置自增的彙編都是一樣的呢!
void test()
彙編:
push rbp
mov rbp, rsp
mov dword ptr [rbp-4], 0
add dword ptr [rbp-4], 1
noppop rbp
ret
不過,賦值的情況下,並且不開啟編譯器優化,它們的彙編**還是有差別的,有興趣的可以試試。
對於內建型別,前置和後置自增或者自減在編譯器優化的情況下,兩者並無多大差別,而對於自定義型別,如無特別需要,人們似乎更加偏愛前置自增或自減,因為後置自增常常會產生臨時物件。
前置 為什麼比後置 效率高
前置 type operator 後置 const type operator int 為了編譯器區分前置和後置 c 規定字尾形式有乙個int型別引數 當函式被呼叫時,編譯器傳遞乙個0做為int引數的值給該函式。不這樣規定,無法區分,因為都僅以自身物件為入參。下面是乙個簡單的例子 class cin...
前置 為什麼比後置 效率高
為了編譯器區分前置和後置 c 規定字尾形式有乙個int型別引數 當函式被呼叫時,編譯器傳遞乙個0做為int引數的值給該函式。不這樣規定,無法區分,因為都僅以自身物件為入參。下面是乙個簡單的例子 class cint cint cint operator 前置的是沒有引數的,並且返回引用 const ...
前置 為什麼比後置 效率高
前置 type operator 後置 const type operator int 為了編譯器區分前置和後置 c 規定字尾形式有乙個int型別引數 當函式被呼叫時,編譯器傳遞乙個0做為int引數的值給該函式。不這樣規定,無法區分,因為都僅以自身物件為入參。下面是乙個簡單的例子 class cin...