什么是引用指针?

时间:2014-03-13 09:42:46

标签: c++ parameter-passing

我最近看到一个声明为:

的函数
void func(type* &param);

我已经知道type* paramtype& param之间的区别。以上与他们有何不同?什么时候使用这个?这样做是否明智?

2 个答案:

答案 0 :(得分: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(没有为operaror<<重载std::ostream


通过查看以下代码可以同化这个概念:

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

std::unique_ptr<int>& x;

在这些示例中,x是对类型(ptr<int>然后std::unique_ptr<int>)的引用,它恰好是具有指针语义的指针/类({{1 }和operator*)。


可以对指针中operator->限定符的位置进行可能有趣的偏离。考虑这两个实例:

  1. const
  2. void func(const int*& ptr)
  3. 他们的意思是:

    1. 指针通过引用常量int
    2. 指针通过对int 的常量引用。
    3. 按照void func(int*const& ptr)的上述类比,它们将是:

      1. ptr
      2. ptr<const int>&
      3. 因此,第一个将无法在函数体中执行ptr<int> const&(因为*ptr = 1是常量),但很乐意执行int

        第二个表现相反,允许ptr = 0(因为指向的int不是常数),而不允许*ptr = 1(因为指针是常量)。

        当然,在以下情况下:

        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); 将被正确释放,指针自动设置为nullptr(空指针)。这样做是为了防止由于缺少x导致的丑陋的分段错误或“未释放指针”错误消息。

        但是使用C ++ 11和C ++ 14时,很少使用指针,甚至更少使用指针。用于的大部分指针都不会被其他标准结构替换(例如,请参阅std::optionalstd::unique_ptrstd::shared_ptrstd::reference_wrapper

答案 1 :(得分: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 = ...,那么影响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)更安全,然后传递type param的地址致电func(&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),然后通过调用type* param传递func(&param)的地址,但同样,由于上述相同的原因,它更安全。< / p>