在C ++中通过引用传递指针的原因?
在哪种情况下你会想在c ++中使用这种性质的代码?
void foo(type *&in) {...} void fii() { type *choochoo; ... foo(choochoo); }
如果您需要修改指针而不是指针所指向的对象,则需要通过引用传递指针。
这与为什么使用双指针相似; 使用对指针的引用比使用指针更安全。
50%的C ++程序员喜欢在删除后将其指针设置为null:
template<typename T> void moronic_delete(T*& p) { delete p; p = nullptr; }
没有参考,你只会改变指针的本地副本,不会影响调用者。
大卫的答案是正确的,但如果还是有点抽象的话,这里有两个例子:
-
您可能希望将所有已释放的指针归零,以便更早地捕获内存问题。 你会做的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);
-
处理链表时 – 通常简单地表示为指向下一个节点的指针:
struct Node { value_t value; Node* next; };
在这种情况下,当您插入到空列表时,您必须更改传入的指针,因为结果不再是
NULL
指针。 这是一个你从一个函数修改一个外部指针的情况,所以它会在它的签名中引用一个指针:void insert(Node* &list) { ... if(!list) list = new Node(...); ... }
这个问题有一个例子。
我不得不使用这样的代码来提供函数来分配内存给传入的指针,并返回它的大小,因为我的公司“对象”使用STL
int iSizeOfArray(int* &piArray) { piArray = new int[iNumberOfElements]; ... return iNumberOfElements; }
这不是很好,但指针必须通过引用传递(或使用双指针)。 如果不是的话,如果内存被传递的值被分配给指针的本地副本,这会导致内存泄漏。
另一种情况,当你可能需要这个是,如果你有stl的指针集合,并希望改变他们使用STLalgorithm。 for_each在c ++ 98中的示例
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(); } };
否则,如果使用changeObject(Object * item)签名,则您有指针的副本,而不是原始的副本。
一个例子是,当你编写一个parsing器函数并将它传给一个源指针来读取时,如果该函数应该将该指针向前推送到parsing器正确识别的最后一个字符之后。 使用对指针的引用可以清楚地知道函数将移动原始指针来更新其位置。
通常,如果要将指针传递给某个函数,并将其移动到某个其他位置,而不是在不影响原始位置的情况下移动该指针的副本,则可以使用对指针的引用。