2014-08-29 96 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