2011-10-01 79 views
2

這個問題是關於代碼解釋,而不是代碼調試。我正在使用的代碼工作。 我使用的是公共代碼,我很好奇,想看看他們的「成長陣」模板,它看起來像這樣的一個:指針轉換解引用指針有什麼用?

template <typename TYPE> 
    TYPE *grow(TYPE *&array, int n, const char *name) 
    { 
     if (array == NULL) return create(array,n,name); 

     bigint nbytes = ((bigint) sizeof(TYPE)) * n; 
     array = (TYPE *) srealloc(array,nbytes,name); 
     return array; 
    } 

和功能srealloc看起來是這樣的:

void *Memory::srealloc(void *ptr, bigint nbytes, const char *name) 
{ 
    if (nbytes == 0) { 
    destroy(ptr); 
    return NULL; 
    } 

    ptr = realloc(ptr,nbytes); 
    if (ptr == NULL) { 
error(); 
    } 
    return ptr; 
} 

請忽略現在的創建函數。我的主要問題是爲什麼他們在模板中進行指針投影並取消引用array?那有什麼好處?如果他們根本沒有*&呢?

謝謝!

回答

2

令牌有很多含義,其中有兩個令你困惑。你不是一個人!作爲一個操作員,它意味着「地址」,您似乎很滿意(這來自C)。但作爲一個類型限定詞,它意味着「參考」,這是完全不同的。第一種含義:

int x ; 
int* p = &x ; // p = address of x (as in C) 

第二層意思:

void f (int& x) { // x is a reference to an int -- its address is passed to f 
    x++ ; 
} 
... 
int y = 99 ; 
f (y) ; // After this call, y is equal to 100 

在這個例子中,該代碼相當於

void f (int* x) { 
    (*x)++ ; 
} 
... 
int y = 99 ; 
f (&y) ; // After this call, y is equal to 100 

此代碼看起來不乾淨,但它更容易理解爲C程序員。

所以...函數聲明

void f (int*& p) ; 

(如你的例子)意味着f可以更改調用函數傳遞的int*參數的值。您的示例代碼對我來說看起來有點棘手,因爲如果它可以直接更改參數,它爲什麼需要返回新值array?但這是一個風格問題,我已經學會了不要在這裏討論這些問題:-)

+0

感謝這些例子和澄清,這非常有幫助。爲了正確理解你,這些函數是否可以在沒有'return'的情況下工作,因爲它們已經直接改變了參數? – Amit

+0

@Amit:確實如此。 – TonyK

+0

你會介意看看我對@DannisZickefoose的評論嗎? – Amit

2
*& 

不是「指針取消引用」。這是對指針的引用。這是必要的,所以增長函數可以改變指針,而不是指針指向的內容。替代方案應該是一個指向指針的指針,就像下面的代碼一樣。

template <typename TYPE> 
TYPE *grow(TYPE **array, int n, const char *name) 
{ 
    if ((*array) == NULL) return create((*array),n,name); 

    bigint nbytes = ((bigint) sizeof(TYPE)) * n; 
    (*array) = (TYPE *) srealloc((*array),nbytes,name); 
    return *array; 
} 
+0

我明白如何替代方案與問題中的當前示例相同,我只是不明白爲什麼它是必要的。爲什麼它不能是'TYPE array',因爲'array'已經是'[size] *'類型的,其中[size]是'int','double'等。 – Amit

+0

我猜我在想爲什麼指針需要改變? – Amit

+1

@Amit:如果可能,它看起來像是要重新分配一個數組。如果它不能,它會分配一個全新的數組並將所有內容移動。在後一種情況下,原始指針最終變得毫無價值,因此立即更新它更安全。這提示了一個參考參數。但是,內存分配函數通常會返回它們分配的內存地址。作者可能只是想確保兩種方法都可用;前者爲安全性,後者爲一致性。 –