Reference & Pointer

A compund type is a type that is defined in terms of another type. C++ has several compund types, two of which–reference and pointers–we’ll cover in this blog.

Reference

A reference defines an alternative name for an object. A reference type “refers to” another type.

int ival = 1024
int &refVal = ival; // refval refers to (is another name for) ival
int &refVal2; // error: a reference must be initialized

Once initialized, a reference remains bound to its initial object. There is no way to rebind a reference to refer to a different object. Because there is no way to rebind a reference, and reference must be initialized.

You should to understand the following program to have a better understanding of reference can not be rebined.

#include "iostream"
using namespace std;

void main() {
	int cinint;
	int i = 42;
	// Reference must be initialize when declaring it.
	int &rpi = i; 
	int ii = 24;
	cout << i << ' ' << rpi << ' ' << ' ' << &i << ' ' << &rpi << endl;
	// It seems like that I rebind rpi to another object.
	// But it isn't.
	rpi = ii; 
	// From this output, we can see that the address of reference
	// variable doesn't change.
	cout << ii << ' ' << rpi << ' ' << &ii << ' ' << &rpi << endl;
	// The effect of the code 'rpi = ii' is to change the value of i.
	cout << i << endl;

	cin >> cinint;
}

A reference is not an object. Instead, a reference is just another name for an already existing object. In addition, we may not define a reference to a reference.

Furthermore, a reference may be bound only to an object, not to a literal or to the result of a more general expression.

int &refVal4 = 10; // error: initializer must be an object
double dval = 3.14;
int &refVal5 = dval; // error: initializer must be an int object

Pointer

Unlike a reference, a pointer is an object in its own right, and it need not to be initialized at the time it is defined. Like other built-in type, pointers defined at block scope have undefined value if they are not initialized.

A pointer holds the address of another object. Because references are not objects, they don’t have addresses. Hence, we may not define a pointer to a reference.

Null Pointer

There are serval ways to obtain a null pointer.

int *p1 = nullptr; // recommended. equivalent to int *p1 = 0;
int *p2 = 0; // directly initializes p2 from the literal constant 0
// must #include cstdlib
int *p3 = NULL; // equivalent to int *p3 = 0;

Note: Older programs sometimes use a preprocessor variable name NULL, which the cstdlib header defines as 0. A preprocessor is a program that runs before a compiler.

It is illegal to assign an int variable to a pointer, even if the variable’s value happens to be 0.

int zero = 0;
int *p = zero; // error: cannot assign an int to a pointer

void* Pointers

The type void* is a special type that an hold the address of any object. Like any other pointer, a void* pointer holds an address, but the type of the object at that address is unknown.

double obj = 3.14, *pd = &obj;
// ok: void* can hold the address value of any data pointer type
void *pv = &obj; // obj can be an object of any type
pv = pd; // pv can hold a pointer to any type

There are only limited number of things we can do with a void* pointer: We can compare it to another pointer, we can pass it to or return it from a function, and we can assign it to another void* pinter. We cannot use a void* to operate on the object it addresses—we don’t know that object’s type, and the type determines what operations we can perform on the object.

Differences Between Reference and Pointer

  • Reference is not an object, it is just another name of an existing object.
  • Reference must be initialized when it is declared.
  • Reference cannot rebind to another object once it is initialized.
  • The address of reference is the same as its refered one.
  • Pointer is an object. It occupies some memory.
  • Pointer doesn’t need to be initialized when it is declared.
  • Pointer can be changed to point another object.
  • The address of pointer is different from the one to which it points.
  • We cannot define a pointer to a reference, because reference is not an object.
  • We can define a reference of a pointer, because pointer is an object.

Pointer to Pointer & Reference to Pointer

We can use the following program to understand pointer to pointer and reference to pointer.

#include "iostream"
using namespace std;

void main() {
	int cinint;
	int i = 42;
	int *pi = &i;
	int *&rpi = pi; // Reference must be initialize when declaring it.
	int *prpi = rpi;
	cout << i << ' ' << *pi << ' ' << *rpi << endl;
	cout << &i << ' ' << pi << ' ' << &pi << endl;
	cout << rpi << ' ' << &rpi << endl;
	cout << *prpi << ' ' << prpi << ' ' << &prpi << endl;

	cin >> cinint;
}

It may be confusing of this code:

int *&rpi = pi;

Here is my explanation.

The easiest way to understand the type of rpi is to read the definitio right to left. The symbol closest to the name of the variable (in this case the & in &rpi) is the one that has the most immediate effect on the  variable’s type. Thus, we know that rpi is a reference. The rest of the declarator determines the type to which rpi refers. The next symbol, * in this case, says that the type rpi refers to a pointer type. Finally, the base type of the declaration says that rpi is a reference to a pointer to an int.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

20 − 3 =

22 − 21 =