C ++中的变量和引用有啥区别? [复制]

Posted

技术标签:

【中文标题】C ++中的变量和引用有啥区别? [复制]【英文标题】:What is the difference between a variable and a reference in C++? [duplicate]C ++中的变量和引用有什么区别? [复制] 【发布时间】:2014-03-05 22:45:26 【问题描述】:

我知道的事实:

    C++ 中有三种类型的变量:变量、指针和引用。 变量是存储实际数据的内存的一种标签。 指针存储变量的地址。 引用是变量的别名。

我的问题:

    根据观察,变量名称和引用的使用是可以互换的。这是真的吗?

    传递变量名作为参数和传递引用有什么区别?例如,

    void func(int a); vs void func2(int& b);

谢谢一百万!

【问题讨论】:

不,名称不能完全互换。例如,coliru.stacked-crooked.com/a/57a496c47639304b 【参考方案1】:

这是一种理解差异的方法:

可以改变状态的对象也称为“变量”。 指针是对象(可变与否)。他们有一个状态。 引用是“昵称”。它们没有状态,但暴露了被引用对象的状态(这就是为什么你不能重新分配引用,它不是一个实际的对象)。

现在,在某些情况下,引用可能被实现为指针,但从语言的角度来看,引用并不是指针,它们实际上是已经存在的对象的附加名称。

由于指针是对象,并且具有状态,因此将指针传递给函数将复制该状态,即指针的状态,而不是指针的状态。然而,引用没有状态,所以如果你传递一个函数的引用,它就是你传递的被引用对象(通过复制)。

通过观察,变量名称和引用的使用是 可交换。这是真的吗?

“引用是昵称”是理解引用的最佳方式。

将变量名作为参数传递有什么区别 并通过参考?例如,

void func(int a); vs void func2(int& b);

第一个实现请求传递的对象的副本。也就是说,在内部 func() 可以对 a 做任何事情,而无需更改传递给 func() 的对象,因为 func() 在内部创建了该对象的副本并操作副本,而不是原始对象。

第二个实现要求“一个已经存在的对象的昵称”。首先,该对象必须存在,如果通过,将在函数内部为其创建一个昵称。那个昵称,引用b,仍然是原始对象的昵称。这意味着对b 进行的任何操作都会影响传递给func2() 的原始对象。

func() 签名说“我需要这个数据,但我不会修改传递的原始对象。”。 func2() 签名说“我需要一个我肯定会修改的对象,传递它以便我可以修改它”。

奖励阶段:

此时,如果您还不了解 const,这可能会很有用:在函数签名中,const 与引用一起使用以指定“只读”参数。

让我澄清一下:

void func3( const int& b);

这里 func3 说:“我需要访问一个对象,但实际上我不会复制它。但是我保证我不会更改那个对象”。

那么,我们为什么需要它?因为有些对象的复制成本很高。 int 复制起来很便宜,所以大多数人都会通过它,而 func() 和 func3() 基本上是等价的(取决于实现,但通常是正确的)。

但是,如果我们想传递一个非常大的对象,比如数据缓冲区,我们真的不想为了应用一些算法而一次又一次地复制它。 所以我们确实想通过引用传递它。但是,根据功能,有时您想提取信息并使用它,因此您只需要“只读”访问参数。在这种情况下,您使用const Object&。但是,如果您需要将算法应用于传递的对象,则需要能够修改它,您可以称之为“写访问”。在这种情况下,您需要使用普通参考。 请求副本基本上意味着您要操作的对象与传递的对象具有相同的状态,但不是传递的对象。

总结一下:

func( T object ) : 我想要一个 T 类型对象的副本; func( T& object ) :我想对 T 类型的对象进行“写访问”-假设我将修改该对象!; func( const T& object ) or func( T const & object ) // which are the same : 我想读取一个对象的状态,但我保证我不会修改它,我想要“只读”访问。

实际上,使用const_cast<> 可能会违反“只读”保证,但这是另一回事,它仅用于一些非常非常非常狭窄的情况。

你需要知道的最后一件事是,如果你有一个成员函数,那么你可以这样做:

class K
public:
     void func() const; // see the const?
;

在这个具体情况下,你说的是函数里面的,基本上相当于: 无效函数(常量K*这个);

在这种情况下,您可以看到 this 是一个指针,但它指向一个 const 对象。这意味着 func() 保证它是 (this) 成员的对象永远不会通过此函数修改(除了某些特定情况,请参阅 mutable 关键字,另一个长故事)。

【讨论】:

【参考方案2】:

假设你有这两个功能:

void addone(int a) 
   a += 1;


void addone_bis(int &a) 
  a += 1;

如果您在 main 函数中调用第一个函数,则值只会在函数 addone 中更改,而不会在 main 中更改,而如果您调用 addone_bis,a 的值也会在main函数。

int main() 
   int test_a = 10;
   int test_b = 11;

   addone(test_a);
   // test_a still equals 10.

   addone_bis(test_b);
   // test_b now equals 12.


我是否正确回答了您的问题?

【讨论】:

这是不正确的。 a + 1 的结果不会写回a。你想要a += 1;++a; 是的,你是对的。已修复,谢谢!【参考方案3】:

您的第一个示例是所谓的按价值传递。这意味着将 ACTUAL 值的副本传递到例程中。

以第二个示例的方式传递时,这就是所谓的 PASSING BY REFERENCE。引用本质上是将变量传递到例程中,这样它的实际值就可以被调用的例程修改而无需去引用。

【讨论】:

以上是关于C ++中的变量和引用有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在c语言编程中,传值方式和传引用方式之间有啥区别?

C 和 C++ 中的“通过引用传递”到底有啥区别?

C++11 中的左值引用和右值引用的区别

基本数据类型和引用数据类型的区别是啥

c#中的引用类型和值类型有啥区别?

63 深拷贝和浅拷贝区别是什么?