繁体   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