2014-08-29 97 views
2

我想了解某些代码,我发现了一些难以理解的代码。C++,参数类型(void *&)的用途是什么?

void BPlusTree::GetKey(int key, void*& keyloc) const { 
    keyloc = keys + key * attrLength; 
    return 0; 
} 

此函数计算密钥值的位置(存储器地址),并把它存储在keyloc变量。

void*&表示空指针的引用。

此处的参考用于将keyloc的更改值反映到调用GetKey的外部函数。

我到现在为止吗?

因此,我认为,在主要功能,当它调用GetKey函数。它需要通过(void*)而不是(void*&)

int main() { 
..... 
int currPos = 0; 
char* key = NULL; 
int result = currNode->GetKey(currPos, (void*&) key); 
} 

为什么使用(void*&)代替(void*)这里?

谢谢。

//我在这里添加示例代码...

#include <regex> 
#include <iostream> 
#include <stdlib.h> 

using namespace std; 
#include <stdio.h> 

void foo(int &a, int &b) { 
a = 10; 
b = 20; 
} 

void foo2(int* &c, int* &d) { 
*c = 10; 
*d = 20; 
} 

void foo3(void* &c, void* &d) { 
*(int*)c = 10; 
*(int*)d = 20; 
} 

int main(void) { 
int a = 0; 
int b = 0; 
int* c = new int; 
int* d = new int; 
void* e = malloc(sizeof(int)); 
void* f = malloc(sizeof(int)); 

foo(a, b); 
printf("A is %d and B is %d\n", a, b); 

foo2(c, d); 
printf("C is %d and D is %d\n", *c, *d); 

foo3((void*&)c,(void*&) d);  // It works fine 
printf("C is %d and D is %d\n", *c, *d); 

foo3((void*)c,(void*) d);  // But it does not work 
printf("C is %d and D is %d\n", *c, *d); 
} 

,是(void *的)问题的一个? :D

+4

如果它是void *,key将是原始void *的副本,并且这意味着当keyloc被修改时,副本被修改,而不是原始键。由于密钥是对原始参考,原始密钥被修改(分配给) – nurettin 2014-08-29 06:57:40

+0

@nurettin当然,这适用于参数。但是真的有必要把*参数*转换成'void *&'(修辞问题)? – juanchopanza 2014-08-29 07:02:00

+0

请发布一些编译的真实自包含代码。 – juanchopanza 2014-08-29 07:02:26

回答

3

是的,你对你的理解非常正确。对于最后一点,也许这将是更容易使用,而不是解释的参考指针...

你可以有

void BPlusTree::GetKey(int key, void** keyloc) const { ... }; 

和呼叫者

char* key = NULL; 
int result = currNode->GetKey(currPos, (void**) &key); 

这里,它应该很明显,为什么你不能使用&(void*) key(void*) key是一个右值,你不能接受它的地址。这就像是采取(key + 0)的地址。当然,key + 0始终只是key,但仅有一个事实,即您有一个加法,意味着您正在查看指针值的副本,而不是原始指针对象。

在处理引用时,没有像指针那样的明确的“地址”操作,但问题是相同的。 GetKey(currPos, (void*) key)不起作用,因为(void*) key是一个右值,而不是左值。 (void*&) keykey转换为“参考void*”,几乎意味着*(void**) &key。这是假装key实际上定义为void*

注意:这通常被认为是非常糟糕的做法。 key实际上可以更好地定义为void*,然后不需要转换就可以拨打GetKey

+0

谢谢你的解释!我只是一个特定的情况(void *)? 我想我需要在使用它之前学习(void *)... – syko 2014-08-29 07:44:01

+0

@SeongYunKo当你将数据存储在某个数据类型中,并试图通过引用(或指针)将它传递给函数,不同的数据类型。 – hvd 2014-08-29 08:42:10