在哪种情况下,您想在C ++中使用这种性质的代码?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
Answers:
如果您需要修改指针而不是指针指向的对象,则希望通过引用传递指针。
这类似于为什么使用双指针。使用对指针的引用比使用指针稍微更安全。
delete
该指针释放该缓冲区或将其重新绑定到内存中的其他位置?还是我弄错了?
[]
操作员超负荷。一种可能的(实际上是自然的)签名是const T &operator[](size_t index) const
。但是你也可以T &operator[](size_t index)
。您可以同时拥有两个。后者会让您做类似的事情myArray[jj] = 42
。同时,您没有提供指向数据的指针,因此调用者无法弄乱内存(例如,意外删除它)。
50%的C ++程序员喜欢在删除后将其指针设置为null:
template<typename T>
void moronic_delete(T*& p)
{
delete p;
p = nullptr;
}
没有引用,您将只更改指针的本地副本,而不会影响调用者。
paranoid_delete
,但是Puppy将其重命名为moronic_delete
。他可能属于其他50%的用户;)总之,简而言之,就是将指针设置为after之后delete
几乎是没有用的(因为它们无论如何都应该超出范围),并且常常会妨碍对“释放后使用”错误的检测。
delete
总体而言是愚蠢的。小狗,我做了一些谷歌搜索,看不到为什么删除是完全没用的(也许我也是一个可怕的谷歌用户;)。您可以多解释一下还是提供链接?
David的答案是正确的,但是如果仍然有点抽象,请参见以下两个示例:
您可能希望将所有释放的指针归零以更早地捕获内存问题。您可以使用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集合,并希望使用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();
}
};
否则,如果使用changeObject(Object * item)签名,则具有指针的副本,而不是原始副本。