简体   繁体   中英

What is the difference between references and normal variable handles in C++?

If C++, if I write:

int i = 0;
int& r = i;

then are i and r exactly equivalent?

That means that r is another name for i. They will both refer to the same variable. This means that if you write (after your code):

r = 5;

then i will be 5.

The Reference is an alias of an object. ie alternate name of an object. Read this article for more information - http://www.parashift.com/c++-faq-lite/references.html

引用是现有对象的别名。

Yep - a reference should be thought of as an for a variable, which is why you can't reassign them like you can reassign pointers (and also means that, even in the case of a non-optimizing compiler, you won't take up any additional storage space). ,这就是为什么您不能像分配指针一样重新分配它们(并且这意味着,即使在非优化编译器的情况下,您也不会占用任何额外的存储空间)。

When used outside of function arguments, references are mostly useful to serve as shorthands for very->deeply->nested.structures->and.fields :)

C++ references differ from pointers in several essential ways:

  • It is not possible to refer directly to a reference object after it is defined; any occurrence of its name refers directly to the object it references.
  • Once a reference is created, it cannot be later made to reference another object; it cannot be reseated. This is often done with pointers.
  • References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.
  • References cannot be uninitialized. Because it is impossible to reinitialize a
    reference, they must be initialized as soon as they are created. In particular, local and global variables must be initialized where they are defined, and references which are data members of class instances must be initialized in the initializer list of the class's constructor.

From Here .

The syntax int &r=i; creates another name ie r for variable i.hence we say that r is reference to i.if you access value of r,then r=0. Remember Reference is moreover a direct connection as its just another name for same memory location.

References are slightly different, but for most intents and purposes it is used identically once it has been declared.

There is slightly different behavior from a reference, let me try to explain.

In your example 'i' represents a piece of memory. 'i' owns that piece of memory -- the compiler reserves it when 'i' is declared, and it is no longer valid (and in the case of a class it is destroyed) when 'i' goes out of scope.

However 'r' does not own it's own piece of memory, it represents the same piece of memory as 'i'. No memory is reserved for it when it is declared, and when it goes out of scope it does not cause the memory to be invalid, nor will it call the destructor if 'r' was a class. If 'i' somehow goes out of scope and is destroyed while 'r' is not, 'r' will no longer represent a valid piece of memory.

For example:

class foo
{
public:
  int& r;
  foo(int& i) : r(i) {};
}

void bar()
{
  foo* pFoo;

  if(true)
  {
    int i=0;
    pFoo = new foo(i);
  }

  pFoo->r=1; // r no longer refers to valid memory
}

This may seem contrived, but with an object factory pattern you could easily end up with something similar if you were careless.

I prefer to think of references as being most similar to pointers during creation and destruction, and most similar to a normal variable type during usage.

There are other minor gotchas with references, but IMO this is the big one.

You are writing definitions here, with initializations. That means that you're refering to code like this:

void foo() {
    int i = 0;
    int& r = i;
}

but not

class bar {
    int m_i;
    int& m_r;
    bar() : i(0), r(i) { }
};

The distinction matters. For instance, you can talk of the effects that m_i and m_r have on sizeof(bar) but there's no equivalent sizeof(foo) .

Now, when it comes to using i and r , you can distinguish a few different situations:

  • Reading, ie int anotherInt = r;
  • Writing, ie r = 5
  • Passing to a function taking an int , ie void baz(int); baz(r); void baz(int); baz(r);
  • Passing to a function taking an int& , ie void baz(int&); baz(r); void baz(int&); baz(r);
  • Template argument deduction, ie template<typename T> void baz(T); baz(r); template<typename T> void baz(T); baz(r);
  • As the argument of sizeof , ie sizeof(r)

In these cases, they're identical. But there is one very important distinction:

std::string s = std::string("hello");
std::string const& cr = std::string("world");

The reference extends the lifetime of the temporary it's bound to, but the first line makes its a copy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM