我最近看到一个声明为:
的函数void func(type* ¶m);
我已经知道type* param
和type& param
之间的区别。以上与他们有何不同?什么时候使用这个?这样做是否明智?
答案 0 :(得分:14)
以上将不仅可以修改指向对象,还可以修改指针本身。例如,请考虑以下代码:
void func(int*& ptr) {
*ptr = 1;
ptr = 0;
}
int main() {
int x = 0;
int* y = &x;
func(y);
}
在执行结束时,x
的值为1
,y
为0
(与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->
限定符的位置进行可能有趣的偏离。考虑这两个实例:
const
void func(const int*& ptr)
他们的意思是:
按照void func(int*const& ptr)
的上述类比,它们将是:
ptr
ptr<const int>&
因此,第一个将无法在函数体中执行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::optional
,std::unique_ptr
,std::shared_ptr
或std::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(¶m)
。
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(¶m)
的地址,但同样,由于上述相同的原因,它更安全。< / p>