为什么 c++ 引用被认为比指针更安全?

2022-01-05 00:00:00 reference pointers c++

当 c++ 编译器为引用和指针生成非常相似的汇编代码时,与指针相比,为什么使用引用更受欢迎(并且被认为更安全)?

When the c++ compiler generates very similar assembler code for a reference and pointer, why is using references preferred (and considered safer) compared to pointers?

我确实看到了

  • C++ 中指针变量和引用变量的区别 讨论了它们之间的差异.
  • Difference between pointer variable and reference variable in C++ which discusses the differences between them.

EDIT-1:

我在看g++为这个小程序生成的汇编代码:

I was looking at the assembler code generated by g++ for this small program:

int main(int argc, char* argv[])
{
  int a;
  int &ra = a;
  int *pa = &a;
}

推荐答案

它被认为更安全,因为很多人听说"它更安全,然后告诉其他人,现在他们也听说"它更安全.

It's considered safer because a lot of people have "heard" that it's safer and then told others, who now have also "heard" that it's safer.

>

没有一个了解引用的人会告诉您它们比指针更安全,它们具有相同的缺陷和失效的可能性.

Not a single person who understands references will tell you that they're any safer than pointers, they have the same flaws and potential to become invalid.

例如

#include <vector>

int main(void)
{
    std::vector<int> v;
    v.resize(1);

    int& r = v[0];
    r = 5; // ok, reference is valid

    v.resize(1000);
    r = 6; // BOOM!;

    return 0;
}

由于对于引用是对象的别名还是绑定到内存位置似乎有些混淆,这里是标准中的段落(草案 3225,部分 [basic.life]) 明确指出引用绑定到存储,并且可以比创建引用时存在的对象寿命更长:

Since there seems to be some confusion about whether a reference is an alias for an object or bound to a memory location, here's the paragraph from the standard (draft 3225, section [basic.life]) which clearly states that a reference binds to storage and can outlive the object which existed when the reference was created:

如果在一个对象的生命周期结束之后并且在该对象占用的存储空间被重用之前或者释放后,在原对象占用的存储位置创建一个新对象,一个指针指向原始对象、引用原始对象的引用或原始对象的名称object 将自动引用新对象,并且一旦新对象的生命周期开始,就可以用于操作新对象,如果:

If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:

  • 新对象的存储恰好覆盖了原始对象占用的存储位置,和
  • 新对象与原始对象的类型相同(忽略顶级 cv 限定符),并且
  • 原始对象的类型不是const限定的,并且如果是类类型,则不包含任何非静态类型为常量限定或引用类型的数据成员,以及
  • 原始对象是 T 类型的最派生对象,新对象是 T 类型的最派生对象(也就是说,它们不是基类子对象).
  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-quali?ers), and
  • the type of the original object is not const-quali?ed, and, if a class type, does not contain any non-static data member whose type is const-quali?ed or a reference type, and
  • the original object was a most derived object of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).

相关文章