Ссылка - это альтернативная метка, псевдоним для объекта, с которым она инициализируется. Как только ссылка инициализирована, ее нельзя изменить, чтобы она стала альтернативной меткой или псевдонимом какого-либо другого объекта. После инициализации ссылка или переменная объекта могут использоваться взаимозаменяемо.
Ссылка имеет некоторые характеристики константного указателя на объект в том смысле, что она инициализируется при определении. И хотя то, на что оно ссылается или на которое можно ссылаться, может быть изменено, ссылка или сам указатель const не могут быть изменены. Однако, поскольку ссылка является альтернативной меткой или псевдонимом, она может фактически существовать или не существовать как объект данных, в отличие от указателя const, который, вероятно, будет существовать, если компилятор не сможет его оптимизировать. И даже если ссылка создается как фактическая сущность компилятором, то есть ведением компилятора, и ее следует игнорировать, поскольку она официально не существует, как человек за кулисами в Изумрудном городе.
В следующих примерах кода приведены примеры, сравнивающие и сравнивающие ссылку с указателем и указателем const:
int myInt; // create a variable of type int, value not initialized
int myInt2 = 3; // create a second variable of type int with a value of 3
int &rInt = myInt; // create a reference to the variable of type int, myInt
rInt = 5; // myInt now has a value of 5, the reference is an alias for myInt
rInt++; // myInt now has a value of 6, the reference is an alias for myInt
rInt = myInt2; // myInt now has the same value as myInt2, a value of 3
int *pInt = &rInt; // pInt points to myInt
(*pInt)++; // increments myInt
pInt++; // increments the pointer which formerly pointed to myInt
int &rInt2; // error C2530: 'rInt2' : references must be initialized
int *pInt2; // just fine, uninitialized pointer is ok
int * const pInt3; // error C2734: 'pInt3' : const object must be initialized if not extern
int * const pInt4 = &myInt; // define and initialize const pointer
pInt4 = &myInt2; // error C3892: 'pInt4' : you cannot assign to a variable that is const
На самом деле существует два вида ссылок: ссылка lvalue
и ссылка rvalue
.
Ссылка lvalue
- это та же ссылка на языке C ++ до C ++ 11. Ссылка rvalue
была введена в C ++ 11, чтобы позволить ссылку на временный объект, чтобы помочь с перемещением, а не копированием и некоторыми другими действиями, когда копирование - это неправильный подход, но перемещение - правильный подход.
Например, сравнение ссылки lvalue и ссылки rvalue в следующих простых строках источника. Поскольку это int
ссылки, это означает, что присвоение нецелого значения приводит к тому, что компилятор выполняет преобразование, которое приводит к временной переменной. Ссылка rvalue
может связываться с временной переменной, а ссылка lvalue
не может.
// assign a double to an int causing creation of temporary
int &rIntd1 = 1.2; // error C2440: 'initializing' : cannot convert from 'double' to 'int &'
int &&rIntd2 = 1.2; // warning C4244: 'initializing' : conversion from 'double' to 'int', possible loss of data
rInt = rIntd2; // myInt from the code above now has a value of 1, 1.2 was truncated when converting from double to int