Skip to main content

C++ Primer Sec. 2.3 Compound Types

Compound Types

References

Reference is not an object. It is an alias. It is just another name for an already existing object.

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

When we define a reference, instead of copying the initializer's value, we bind the reference to its initializer. 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, references must be initialized.

When we assign to a reference, we are assigning to the object to which the reference is bound.

int i = refVal; //OKay i= 1024

Because references are not objects, we may not define a reference to a reference.
We can define multiple references in a single definition. Each identifier that is a reference must be preceded by the & symbol:

int &r = i, r2 = i2; // r is a reference bound to i; r2 is an int
int &r3 = i3, &r4 = i2; // both r3 and r4 are references

With two exceptions, the type of a reference and the object to which the reference refers must match exactly.
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, other wise if is it correct, then refVal5 is referring to a temporary int converted from dval.

Pointers

a pointer is an object in its own right. Pointers can be assigned and copied.
a pointer need not be initialized at the time it is defined.

int *ip1, *ip2; // both ip1 and ip2 are pointers to int
double dp, *dp2; // dp2 is a pointer to double; dp is a double

Because references are not objects, they don’t have addresses. Hence, we may not define a pointer to a reference.
With two exceptions the types of the pointer and the object to which it points must match.

double deal;
double *pd = &dval; // ok: initializer is the address of a double
double *pd2 = pd; // ok: initializer is a pointer to double
int *pi = pd; // error: types of pi and pd differ
pi = &dval; // error: assigning the address of a double to a pointer to int
int &r2 = *p; // & is part of the declaration; * is the dereference operator

A null pointer does not point to any object.

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

nullptr is a literal that has a special type that can be converted to any other pointer type.

ModernC++ programs generally should avoid using NULL and use nullptr instead.
It is illegal to assign an int variable to a pointer, even if the variable’s value happens to be 0.

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

Uninitialized pointers are a common source of run-time errors.

Given two valid pointers of the same type, we can compare them using the equality (==) or inequality (!=) operators.

The type void* is a special pointer type that can hold the address of any object.
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

Understanding Compound Type Declarations

// i is an int; p is a pointer to int; r is a reference to int
int i = 1024, *p = &i, &r = i;
int* p1, p2; // p1 is a pointer to int; p2 is an int
int *p1, *p2; // both p1 and p2 are pointers to int

Pointers to Pointers

int ival = 1024;
int *pi = &ival; // pi points to an int
int **ppi = π // ppi points to a pointer to an int

References to Pointers

A reference is not an object. Hence, we may not have a pointer to a reference. However, because a pointer is an object, we can define a reference to a pointer.

int i = 42;
int *p; // p is a pointer to int
int *&r = p; // r is a reference to the pointer p
r = &i; // r refers to a pointer; assigning &i to r makes p point to i
*r = 0; // dereferencing r yields i, the object to which p points; changes i to 0

The easiest way to understand the type of r is to read the definition right to left. The symbol closest to the name of the variable (in this case the & in &r) is the one that has the most immediate effect on the variable’s type. Thus, we know that r is a reference.

Comments