2014-03-13 47 views
8

我最近看到一个被定义为一个函数:什么是参考指针?

void func(type* &param); 

我已经知道type* paramtype& param之间的差异。上述与他们有什么不同?何时使用这个?这样做是可取的吗?

+9

它和'type&param'一样,这里的类型是'type *'。 – songyuanyao

回答

14

以上将能够修改不仅指向对象,而且指针本身。作为一个例子,考虑下面的代码:

void func(int*& ptr) { 
    *ptr = 1; 
    ptr = 0; 
} 

int main() { 
    int x = 0; 
    int* y = &x; 
    func(y); 
} 

在执行结束时,x具有值1y0(如你can see)。

注意,为举例起见我使用0作为空指针,但如果使用的是C++ 11你should probably use nullptr instead(其不具有用于std::ostream重载operaror<<)。


这个概念可以可能通过下面的代码考虑看看被同化:

template<class Type> using ptr = Type*; 
ptr<int>& x; 

std::unique_ptr<int>& x; 

在这些实例中,x是对类型的引用(ptr<int>然后std::unique_ptr<int>),这恰好是指针/类与指针语义(operator*operator->)。


可能会对指针中的const限定符的位置做出可能有趣的离题。考虑以下两种情况:

  1. void func(const int*& ptr)
  2. void func(int*const& ptr)

它们的意思是:

  1. 指针参考恒定INT
  2. 指针通过不断引用int

经过与ptr上面的比喻,他们将是:

  1. ptr<const int>&
  2. ptr<int> const&

因此,首先会失败的函数体执行*ptr = 1(因为int是恒定的),但会愉快地执行ptr = 0

第二个会反过来,允许*ptr = 1(因为指向的int不是常量),而不允许ptr = 0(因为指针是常量)。

当然,在的情况下:

void func(const int*const& ptr) 

这在ptr类比是ptr<const int> const&,他们都不会被允许。


,何时使用呢?这样做是可取的吗?

像每一个功能一样,当你需要它时,你会发现它的实用性。但是就像一般的想法一样,有些人在释放一个动态分配的资源后用它来重置指针(我不推荐这个,见下文)。

让我们这个例子:

free_my_int(int*& ptr) { 
    delete ptr; 
    ptr = nullptr; 
} 

int* x = new int(42); 
free_my_int(x); 

在执行结束时,x会被正确地释放和指针自动设置为nullptr(空指针)。这样做是为了防止由于丢失ptr = nullptr导致丑陋的分段错误或“释放的指针未被分配”错误消息。

但是在C++ 11和C++ 14中,指针的使用非常少,对指针的引用更少。大多数用于指针的指针不会被其他标准构造替换(例如,参见std::optional,std::unique_ptr,std::shared_ptrstd::reference_wrapper)。

2

我们来比较一下这三种选项:

  • void func(type* param); // 'param' is a 'type*' variable
  • void func(type& param); // 'param' is a reference to a 'type' variable
  • void func(type*& param); // 'param' is a reference to a 'type*' variable

void func(type* param) 
{ 
    type x; 
    ... 
    param = &x; 
    // Argument 'param' is regarded as a local variable in this function, 
    // so setting 'param = ...' will have no effect outside this function 
} 

当然,如果你这样做*param = ...,T当它影响由param指出的内存的内容。例如,您也可以执行param[5] = ...,并影响该内存空间中的其他区域。


void func(type& param) 
{ 
    type x; 
    ... 
    param = x; 
    // Argument 'param' is regarded as a reference to a variable outside this 
    // function, so setting 'param = ...' will effect the referenced variable 
} 

在这里,你将只能改变引用变量本身,因此它比声明函数为void func(type* param)安全,然后通过调用func(&param)合格type param地址。


void func(type*& param) 
{ 
    type x; 
    ... 
    param = &x; 
    // Argument 'param' is regarded as a reference to a variable outside this 
    // function, so setting 'param = ...' will effect the referenced variable 
} 

这类似于声明用作void func(type** param),然后通过调用func(&param)传递的type* param地址,但同样,它是上面提到的同样的理由更安全。