在 C++ 中通过引用传递指针的原因?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10240161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:47:12  来源:igfitidea点击:

Reason to Pass a Pointer by Reference in C++?

c++pointersreference

提问by Matthew Hoggan

Under which circumstances would you want to use code of this nature in c++?

在什么情况下您希望在 C++ 中使用这种性质的代码?

void foo(type *&in) {...}

void fii() {
  type *choochoo;
  ...
  foo(choochoo);
}

回答by David Z.

You would want to pass a pointer by reference if you have a need to modify the pointer rather than the object that the pointer is pointing to.

如果您需要修改指针而不是指针指向的对象,您可能希望通过引用传递指针。

This is similar to why double pointers are used; using a reference to a pointer is slightly safer than using pointers.

这类似于为什么使用双指针;使用对指针的引用比使用指针稍微安全一些。

回答by fredoverflow

50% of C++ programmers like to set their pointers to null after a delete:

50% 的 C++ 程序员喜欢在删除后将指针设置为 null:

template<typename T>    
void moronic_delete(T*& p)
{
    delete p;
    p = nullptr;
}

Without the reference, you would only be changing a local copy of the pointer, not affecting the caller.

如果没有引用,您只会更改指针的本地副本,而不会影响调用者。

回答by Antoine

David's answer is correct, but if it's still a little abstract, here are two examples:

大卫的回答是正确的,但如果还是有点抽象,这里有两个例子:

  1. You might want to zero all freed pointers to catch memory problems earlier. C-style you'd do:

    void freeAndZero(void** ptr)
    {
        free(*ptr);
        *ptr = 0;
    }
    
    void* ptr = malloc(...);
    
    ...
    
    freeAndZero(&ptr);
    

    In C++ to do the same, you might do:

    template<class T> void freeAndZero(T* &ptr)
    {
        delete ptr;
        ptr = 0;
    }
    
    int* ptr = new int;
    
    ...
    
    freeAndZero(ptr);
    
  2. When dealing with linked-lists - often simply represented as pointers to a next node:

    struct Node
    {
        value_t value;
        Node* next;
    };
    

    In this case, when you insert to the empty list you necessarily must change the incoming pointer because the result is not the NULLpointer anymore. This is a case where you modify an external pointer from a function, so it would have a reference to pointer in its signature:

    void insert(Node* &list)
    {
        ...
        if(!list) list = new Node(...);
        ...
    }
    
  1. 您可能希望将所有释放的指针归零以更早地捕获内存问题。你会做的 C 风格:

    void freeAndZero(void** ptr)
    {
        free(*ptr);
        *ptr = 0;
    }
    
    void* ptr = malloc(...);
    
    ...
    
    freeAndZero(&ptr);
    

    在 C++ 中做同样的事情,你可能会这样做:

    template<class T> void freeAndZero(T* &ptr)
    {
        delete ptr;
        ptr = 0;
    }
    
    int* ptr = new int;
    
    ...
    
    freeAndZero(ptr);
    
  2. 在处理链表时 - 通常简单地表示为指向下一个节点的指针:

    struct Node
    {
        value_t value;
        Node* next;
    };
    

    在这种情况下,当您插入空列表时,您必须更改传入的指针,因为结果不再是NULL指针。在这种情况下,您从函数修改外部指针,因此它的签名中将包含对指针的引用:

    void insert(Node* &list)
    {
        ...
        if(!list) list = new Node(...);
        ...
    }
    

There's an example in this question.

这个问题中有一个例子。

回答by mathematician1975

I have had to use code like this to provide functions to allocate memory to a pointer passed in and return its size because my company "object" to me using the STL

我不得不使用这样的代码来提供函数来为传入的指针分配内存并返回其大小,因为我的公司使用 STL 向我“对象”

 int iSizeOfArray(int* &piArray) {
    piArray = new int[iNumberOfElements];
    ...
    return iNumberOfElements;
 }

It is not nice, but the pointer must be passed by reference (or use double pointer). If not, memory is allocated to a local copy of the pointer if it is passed by value which results in a memory leak.

这不好,但指针必须通过引用传递(或使用双指针)。如果不是,则将内存分配给指针的本地副本(如果按值传递会导致内存泄漏)。

回答by BarbaraKwarc

One example is when you write a parser function and pass it a source pointer to read from, if the function is supposed to push that pointer forward behind the last character which has been correctly recognized by the parser. Using a reference to a pointer makes it clear then that the function will move the original pointer to update its position.

一个例子是当你编写一个解析器函数并向它传递一个源指针来读取时,如果函数应该将该指针向前推到最后一个被解析器正确识别的字符后面。使用对指针的引用可以清楚地表明该函数将移动原始指针以更新其位置。

In general, you use references to pointers if you want to pass a pointer to a function and let it move that originalpointer to some other position instead of just moving a copy of it without affecting the original.

通常,如果要将指针传递给函数并让它将原始指针移动到其他位置,而不是仅移动它的副本而不影响原始指针,则可以使用对指针的引用。

回答by Nine

Another situation when you may need this is if you have stl collection of pointers and want to change them using stl algorithm. Example of for_each in c++98.

另一种可能需要这样做的情况是,如果您有 stl 指针集合并想使用 stl 算法更改它们。c++98 中 for_each 的示例。

struct Storage {
  typedef std::list<Object*> ObjectList;
  ObjectList objects;

  void change() {
    typedef void (*ChangeFunctionType)(Object*&);
    std::for_each<ObjectList::iterator, ChangeFunctionType>
                 (objects.begin(), objects.end(), &Storage::changeObject);
  }

  static void changeObject(Object*& item) {
    delete item;
    item = 0;
    if (someCondition) item = new Object();
  } 

};

Otherwise, if you use changeObject(Object* item)signature you have copy of pointer, not original one.

否则,如果您使用changeObject(Object* item)签名,您将拥有指针的副本,而不是原始指针。