簡體   English   中英

了解C ++運算符重載

[英]Understanding C++ operator overloading

我今天正在閱讀哈希競賽的源代碼,並且發現:

#define BYTES_IN_BLOCK 1024

struct block{
    uint8_t v[BYTES_IN_BLOCK];

    block(){ memset(v, 0, BYTES_IN_BLOCK); }
    uint64_t& operator[](uint8_t i){ return *(uint64_t*)(v + 8 * i); }
};

然后,在代碼的后面,有以下內容:

state = new block[cost]; // cost is a uint32_t (like 1024)
// Probably 50 lines of code.
block prev_block;

prev_block = state[foo]; // foo is a uint32_t

我不知道這是在做什么。 現在,我了解C,但是對C ++的了解不多。 在這里忍受我一秒鍾。

這部分: return *(uint64_t*)(v+8*i)應該返回一個uint64_t ,並且在我測試它時這樣做:

state->v[8*10] = 12;
uint64_t bar = *(uint64_t*)(v+8*10);
printf("%" PRIu64 "\n", bar);

這樣就很有意義了。

但是這個:

prev_block = state[foo];

沒有意義。 由於stateblock* ,因此prev_block現在應為“ state ,對嗎? 但這不是因為它們的數組不同。

state->v[8*12] = 12;
printf("%" PRIu64 "\n", (*state)[12]);
prev_block = state[12];
printf("%" PRIu64 "\n", (*(&prev_block))[12]);

那么,這到底是怎么回事?

state = new block[cost];
prev_block = state[foo];

類似於:

int* arr = new int[size];
int a = arr[index];

那是基本的C ++。 我不確定為什么會造成混淆。

您正在混淆此處涉及的兩個operator[] 在上一個示例中,您設置了state[0][12] = 12 ,並將其與state[12][12] 由於state是一個block* ,所以state[n]只是普通的數組訪問; 它不會調用block定義的operator[]

這里有很多概念的困惑。 我將介紹所有看到的內容,因為它們都很重要,而不僅僅是即時答案。

state是一個指向塊的指針,但是state[0]應該只是一個塊,特別是state中的第一個塊以及*state的結果。

prev_block = state[foo];

塊中的所有數據都很簡單,只是一個獨立的字節數組,因此它應該可以直接復制,而無需任何特殊幫助。 prev_block = state[foo]應該將state [foo]復制到prev_block。 由於是副本,因此尋址將有所不同。

在提供的打印輸出代碼中:

state->v[8*12] = 12;

為清晰起見,將他分解。 state->將訪問狀態數組的第一個元素。 state->v[8*12]將訪問狀態[0]的v [8 * 12]。 state->v[8*12] = 12; 將狀態[0]的v [8 * 12]設置為12。這意味着v的字節96將為12。要引用其他狀態,可以使用(state + array_index)->v[8*12]; state[array_index].v[8*12]; 我發現后者更具可讀性。

printf("%" PRIu64 "\n", (*state)[12]);

(*state)給出數組中的第一個狀態,即AKA state[0] (*state)[12]使用state[0]的[]運算符,定義為uint64_t& operator[](uint8_t i){ return *(uint64_t*)(v + 8 * i); } uint64_t& operator[](uint8_t i){ return *(uint64_t*)(v + 8 * i); }

這將返回一個64位int,該int從狀態[0] .v [12 * 8]的地址開始,由數組v(v [96]至v [103]的后8個字節)組成,結果為12 0,0,0,0,0,0,0)。 根據系統的字節序,這將是12或一個令人敬畏的大數字。 包裝的printf將打印返回的數字。

prev_block = state[12];

假設state = new block[cost];創建了足夠的塊,則將狀態數組的第13個元素復制到prev_block state = new block[cost]; 沒什么了不起的,但是除了零之外,什么也沒有,因為唯一設置了任何值的狀態是state [0]。 您要么想在這里復制state[0] ,要么要寫幾行到state[12]

printf("%" PRIu64 "\n", (*(&prev_block))[12]);

*和&在完成任何操作之前會互相抵消。 然后它將打印出使用如上所述的block []運算符的結果。 應該為零。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM