使用最大優化設定編譯和運行此代碼似乎給出了相同的結果。
#include <stdio.h>
class A
{
public:
A() { }
const int* begin() const { return a; };
const int* end() const { printf("end\n"); return a 3; };
bool isTrue() const { return true; }
int a[4];
};
const A a{};
class B
{
public:
const A& operator[](size_t) const { printf("B called\n"); return a; }
};
int main()
{
const B b{};
if (!b[0].isTrue()) return -1;
for (const auto& x : b[0]) printf("%d\n", x);
}
我在 B 型別的常量物件上呼叫 b[0] 兩次,運算子 [] 回傳 A 型別的常量物件。
為什么“B called”會列印兩次?為什么代碼不能在旁邊保存 b[0] 并在其上運行不同的功能?(由于函式是 const 函式,它們將回傳相同的結果......)
uj5u.com熱心網友回復:
為什么“B called”會列印兩次?
對于初學者,因為您在 main.js 中參考b[0]了兩次。并且因為printfoperator 函式內部的陳述句表明訪問b[0]. 所以編譯器不能假設你的 printf 只是為了除錯——它必須為每次呼叫呼叫一次。
使用 Godbolt,如果我們洗掉 printf 陳述句并進行評估,我們可以看到代碼經過高度優化,可以列印03 次而無需任何呼叫。
優化:https ://godbolt.org/z/E8czPdr5W
uj5u.com熱心網友回復:
operator[]與任何其他函式一樣,它是一個普通函式,并且由于 C 沒有純函式的概念,因此編譯器必須假設每個函式都有副作用。一個這樣的副作用是你的printf電話。如果您優化對 的呼叫之一operator[],您的程式行為可能會改變(這里它只會列印一次而不是兩次)。想象一下,代替printf您呼叫資料庫或其他重要的東西。如果它只是被優化掉,那將是非常糟糕的。
另請注意,const成員函式與純函式不同。const意味著它不能修改您呼叫成員函式的實體,但您仍然可以更改全域變數。而且你甚至不能保證成員函式不會改變實體的狀態,因為你可以在某些條件下const拋棄。const
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/445361.html
