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

Mat*_*gan 89 c++ pointers reference

在哪种情况下你想在c ++中使用这种性质的代码?

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

void fii() {
  type *choochoo;
  ...
  foo(choochoo);
}
Run Code Online (Sandbox Code Playgroud)

Dav*_* Z. 131

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

这类似于使用双指针的原因; 使用对指针的引用比使用指针稍微安全一些.

  • 所以类似于指针的指针,除了一个较少的间接级别的传递引用语义? (14认同)
  • @威廉你能详细说明吗?听起来很有趣。这是否意味着该类的用户可以获取指向内部数据缓冲区的指针并对其进行读取/写入,但是它不能(例如)使用“删除”释放该缓冲区或将该指针重新绑定到内存中的其他位置?还是我弄错了? (2认同)
  • @BarbaraKwarc当然。假设您有一个动态数组的简单实现。自然地,您会重载`[]`运算符。一个可能的(实际上是自然的)签名是const T&operator [](size_t index)const。但是你也可以有`T&operator [](size_t index)`。您可以同时拥有两个。后者会让您执行诸如“ myArray [jj] = 42”之类的操作。同时,您没有提供指向数据的指针,因此调用者无法弄乱内存(例如,意外删除内存)。 (2认同)

fre*_*low 62

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

template<typename T>    
void moronic_delete(T*& p)
{
    delete p;
    p = nullptr;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我喜欢这个名字; ) (19认同)
  • 这个例子清楚地表明了解. (3认同)
  • 我会用听起来很愚蠢来找出答案:为什么它被称为愚蠢的删除?我错过了什么? (3认同)
  • @Sammaron 如果你查看历史,函数模板曾经被称为`paranoid_delete`,但Puppy 将其重命名为`moronic_delete`。他可能属于其他 50% ;) 无论如何,简短的回答是在 `delete` 之后设置指向 null 的指针几乎从来没有用过(因为它们应该超出范围,无论如何)并且经常妨碍检测“免费使用后使用” “虫子。 (2认同)
  • @Sammaron,C++ 现在有“智能指针”,它封装了常规指针,并在它们超出范围时自动为您调用“删除”。智能指针比 C 风格的哑指针更受欢迎,因为它们完全消除了这个问题。 (2认同)

Ant*_*ine 14

大卫的答案是正确的,但如果它仍然有点抽象,这里有两个例子:

  1. 您可能希望将所有释放的指针归零,以便更早地捕获内存问题.你做的C风格:

    void freeAndZero(void** ptr)
    {
        free(*ptr);
        *ptr = 0;
    }
    
    void* ptr = malloc(...);
    
    ...
    
    freeAndZero(&ptr);
    
    Run Code Online (Sandbox Code Playgroud)

    在C++中也可以这样做,你可能会这样做:

    template<class T> void freeAndZero(T* &ptr)
    {
        delete ptr;
        ptr = 0;
    }
    
    int* ptr = new int;
    
    ...
    
    freeAndZero(ptr);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 处理链表时 - 通常只是表示为指向下一个节点的指针:

    struct Node
    {
        value_t value;
        Node* next;
    };
    
    Run Code Online (Sandbox Code Playgroud)

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

    void insert(Node* &list)
    {
        ...
        if(!list) list = new Node(...);
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

这个问题有一个例子.


mat*_*975 8

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

 int iSizeOfArray(int* &piArray) {
    piArray = new int[iNumberOfElements];
    ...
    return iNumberOfElements;
 }
Run Code Online (Sandbox Code Playgroud)

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