参考类型的定义是什么?

时间:2014-07-18 14:36:25

标签: c++ reference

如何以正式和严格的方式定义(解释)C ++中的引用类型是什么?

我尝试谷歌,并研究了Stroustrup" The C ++ Programming Language",但我没有看到这个概念的定义。

4 个答案:

答案 0 :(得分:2)

引用是别名,是对象的备用名称。它本身不是一个对象(并且以这种方式不是一个指针,即使它们的一些用途与指针的使用重叠)。

参考文献对其处理有一定的限制,与其非对象性有关。例如,您无法创建引用数组。它们必须在声明后立即初始化(绑定,就位),因为它们可能不存在别名的对象。

然而,您可以存储它们,并且它们遵守自动变量或成员变量的规则。他们的一个用途是通过C ++的值传递函数调用。

请注意,const引用具有作为别名的简洁副作用:当绑定到临时(即未命名)对象时,它们为所述对象赋予名称,因此将其生命周期延长到引用本身的生命周期。

{ // Block scope
     Foo fooVal = makeFoo(); // Say makeFoo() returns a (temporary, unnamed) Foo
     // Here the temporary Foo is dead (fooVal is a copy).

     // Foo &fooRef = makeFoo(); // Error, reference is non-const
     Foo const &fooCRef = makeFoo(); // All good

     // ...

     // The second temporary is still alive
     fooCRef.doSomethingFunny(); // Works like a charm !

} // The second temporary dies with fooRef

但要注意,有可能(虽然设法)让对象超出范围,引用仍然指向它。然后,您将拥有悬空引用,这些引用不再被使用(这样做将是未定义的行为)。

Foo *fooPtr = new Foo; // Here is a Foo
Foo &fooRef = *fooPtr; // Here is an alias for that Foo

delete fooPtr; // Here is the end of that Foo's life

fooRef.doSomethingFunny(); // Here comes trouble...

答案 1 :(得分:1)

关于

  

如何以正式和严格的方式定义(解释)C ++中的引用类型是什么?

C ++ 11标准在其

中给出了引用类型的以下正式和严格定义

§8.3.2/ 1

  

在声明T D中,其中D具有任何一种形式
  & attribute-specifier-seq opt D1
  && attribute-specifier-seq opt D1
  并且声明T D1中的标识符类型是“ derived-declarator-type-list T”,然后是类型   D的标识符是“ derived-declarator-type-list T的引用。”


但是,如果您对C ++引用实际上更感兴趣(除了该术语的口语使用),那么请在表达式中检查其含义的定义,

§5.5

  

如果表达式最初具有”T引用“类型(8.3.2,8.5.3),则类型将在T之前调整为const   进一步的分析。表达式指定由引用表示的对象或函数,以及   表达式是左值或x值,具体取决于表达式

实际上,这意味着引用充当别名

您可以将引用视为自动解除引用的{{1}}指针,它解释了大多数行为,但引用不一定占用存储(编译器可能能够完全优化它)。 / p>

答案 2 :(得分:0)

C和C ++之间的主要区别(除了对象和类!)是引用。 引用就像是指向变量的const指针。分配引用有点像使用指针,但使用&不*并且你不需要区别。区别在于您为指针分配地址,但为引用变量分配变量。 下面的行表明a的值被复制到aref中。但它不是,而是aref是对变量a的引用。一旦分配,aref与a相同。对aref的任何更改都会更改为以下示例

int& aref = a;

 #include <stdio.h>
 #include "stdafx.h"

  int main()
   {
      int a=9;
      int & aref = a;
      a++;
      cout << "The value of a is %i\n" << aref;
      return 0;
    }

还要记住

  1. 引用必须始终引用某些内容。不允许使用NULL。

  2. 创建时必须初始化引用。未分配的引用不可存在。

  3. 初始化后,无法将其更改为其他变量。

  4. 如果有帮助,请通知我,thanx

答案 3 :(得分:0)

根据一些专家的观点,引用类型本身不是C ++引用,而是与值类型相反。我给出了两个略有不同的定义-值类型和引用类型。

https://abseil.io/blog/20180531-regular-types

第一个是Titus Winters的博客帖子,他是负责C ++标准库的C ++小组委员会主席。

根据泰特斯·温特斯(Titus Winters)的观点,值类型和引用类型之间的区别在于复制行为。复制值类型时,将获得两个独立的对象,这些对象首先相等,但是在修改二者之一后可能会有所不同。复制引用类型时,将获得两个对象,它们引用相同的数据。

引用类型不拥有其数据。有些引用类型允许修改引用的数据(例如,跨度),有些则不允许(例如,string_view)。给出的两个示例对于传递函数参数都非常有用。函数的调用者确保在函数调用期间不会破坏引用类型的基础数据(就像普通C ++引用一样)。

https://docs.microsoft.com/en-us/cpp/cpp/value-types-modern-cpp?view=vs-2019

Microsoft文档将引用类型与多态类型(具有至少一个虚函数或成员变量的类型)同义,并将值类型作为非多态类型。 (非多态类型被Bjarne Stroustrup称为具体类型。)

值类型与内存和布局控制有关,引用类型与标识有关。

值类型允许编译器直接访问成员,由于运行时多态性,引用类型需要间接访问。

根据Microsoft的引用类型是不可复制的(以防止切片)。

所以语义有所不同,因为泰特斯·温特斯(Titus Winters)通过引用类型的实际复制行为来定义引用类型。