2011-10-01 55 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:如果可能,它看起来像是要重新分配一个数组。如果它不能,它会分配一个全新的数组并将所有内容移动。在后一种情况下,原始指针最终变得毫无价值,因此立即更新它更安全。这提示了一个参考参数。但是,内存分配函数通常会返回它们分配的内存地址。作者可能只是想确保两种方法都可用;前者为安全性,后者为一致性。 –