Is there any advantage of using references instead of pointers in c++?
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
例如,我有两个执行相同操作的函数:
1 2 3 4
| int func(int &a)
{
return a+1;
} |
和
1 2 3 4
| int func2(int *a)
{
return *a+1;
} |
调用这些函数中的任何一个时,使用func比使用func2有什么好处?
- 在我看来,唯一的优势是能够接受空参数。关于这个话题,这里已经有一些好问题了。
- 请参阅stackoverflow.com/questions/57483/…
- 我之所以这样问是因为我们团队项目中的一个朋友坚持我们使用引用而不是指针,声称引用比指针"优越"。我想我会坚持使用指针,因为我在做了一些C项目后更习惯了它。
- @用户803253:是的,只要你能使用它们,它们都是优秀的——它们承认的错误比指针少。
- @但是如果你能很好地管理好指针就不行了?
- @用户803253:能够很好地管理指针不是问题。这是一个防止每个人都犯"愚蠢"错误的问题。例如,向需要指向数据的指针的函数传递空指针。如果编译器可以为您捕捉错误,为什么不利用这个事实呢?
- 不能直接为引用赋值为空,但可以为指针赋值。
- 不能重新分配引用以指向其他对象,但指针可以。
根据具体情况,这两者都可以是利弊。
- 实际上,引用可以为空。但要想做到这一点比用指针要困难得多。事实上,引用只是语法上的糖分。
- @弗拉德拉扎伦科,没错,但它有点破坏了使用它们的目的。最后你得到了一些非常糟糕的代码。
- @如果我没有弄错的话,构造一个null引用是未定义的行为。
- @vladdlazarenko只有在一个畸形的程序中才能引用null,所以说它们不能是null基本上是正确的。
- 引用不仅仅是句法上的糖分。结构/类可以包含引用,因此该引用实际上是由位构成的实际运行时值。
- @他指的是指针的句法糖。
- @sethcarnegie,不幸的是,很容易意外地创建一个空引用。每天都会创建格式错误的程序。
- 伙计们,我的意思是引用并没有映射到任何"物理"实体中,并且只存在于语言级别上。另一方面,指针存在于较低的级别。也就是说,它们被加载到CPU的寄存器中,用于读/写内存。例如,它和模板一样是一种句法糖分。理解它们存在的原因以及编译器如何处理它们以生成较低级别的代码是很重要的。它还显示了函数等作者的意图,但是它被"合成"成一个指针,或者POD的副本,或者被完全消除。呵呵。
- @Markransom是的,但是将畸形程序中未定义的行为包含到我们可以做和不能做的定义中是毫无意义的。所以一个参考不能是null,因为标准是这样说的,任何其他的行为都不在宇宙的范围之内。你不这么认为吗?
- @sethcarnegie,我的态度被一个结果为空的引用所导致的一个多天调试会话所改变。甚至不是我的密码!
- 一个引用被映射到一个物理实体(具有物理实现),并被加载到CPU寄存器等中。只有在代码的词法范围内的引用才能被视为编译时别名,特别是当它们只是对同一范围内的局部变量的引用时。如果我这样引用:int &x = a->b.c[i][j].foo;。编译器不会用原始表达式替换每一次出现的x。此外,a、i和j可能发生变化!不,必须有一个小指针藏在某个地方,代表现在用x表示的int的地址。
- 如果引用出错(空或无效),则根本原因将是指针。
您的两个功能都是错误的。因为它们不修改传入的参数,所以应该将它们作为常量,如下所示:
1 2 3 4 5 6 7 8 9
| int func(const int &a)
{
return a+1;
}
int func2(const int *a)
{
return *a+1;
} |
下面是参考的一个优点,我可以将rvalues传递到参考版本中:
1 2
| func(10);
func(func(func(10))); |
我不能用指针版本来实现。
- 施工部分是否必要?我以为是为了安全?
- @用户803253:如果你认为好的设计是必要的,我也是。不,这不仅仅是为了安全。它还允许您将实际的常量对象传递到函数中。为什么用户不能将常量对象传递到不修改传递对象的函数中?不允许用户这样做,就像我说的,是糟糕的设计。
- 我明白了,谢谢你的意见
- 我不会说错的。我想他们可以改进。
- @亚历克斯:我说错了。当一个改进需要这么少的努力,并且没有明显的缺点时,不去做是错误的。
指针更灵活,它也可以在声明中预定义,如:
1
| int func2(int *a = nullptr); |
这在你的简单案例中不起作用,但在许多其他案例中却起作用。
指针也可以更容易地用于其他事情,如存储在列表中、打印列表和其他事情。
是的,不能重新分配引用。
如果A是一个重载标准C++操作符(例如,运算符[]或操作符*)的对象,则客户端可以使用更标准的C++语法,如[i],而不是->运算符[](i)或(*a)[i]。