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

Popular posts from this blog

C++ Primer Sec. 2.6 Defining our own data structures

Defining our own data structures Class definition must have ; at the end. Preprocessor The most common technique for making it safe to include a header multiple times relies on the preprocessor. #include Header guards #ifndef SALES_DATA_H #define SALES_DATA_H #include struct Sales_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; }; #endif SALES_DATA_H can be any name, just it has to be unique throughout the program. preprocessor variables usually are written in all uppercase.

C++ Primer Sec. 2.5 Dealing with Types

Dealing with Types type alias typedef double wages; // wages is a synonym for double typedef wages base, *p; // base is a synonym for double, p for double* C++11: alias declaration using SI = Sales_item; // SI is a synonym for Sales_item As usual, a const that appears in the base type modifies the given type. The type of pstring is “pointer to char.” So, const pstring is a constant pointer to char—not a pointer to const char. It can be tempting, albeit incorrect, to interpret a declaration that uses a type alias by conceptually replacing the alias with its corresponding type. typedef char *pstring; const pstring cstr = 0; // cstr is a constant pointer to char const pstring *ps; // ps is a pointer to a constant pointer to char const char *cstr = 0; // wrong interpretation of const pstring cstr C++11: auto. auto tells the compiler to deduce the type from the initializer. The initializers for all the variables in the declaration using auto must have types that a...

C++ Primer Sec.2.4 const qualifier

const Qualifier Because we can’t change the value of a const object after we create it, it must be initialized just as reference const int i = get_size(); // ok: initialized at run time const int j = 42; // ok: initialized at compile time const int k; // error: k is uninitialized const when we use an object to initialize another object, it doesn’t matter whether either or both of the objects are consts. int i = 42; const int ci = i; // ok: the value in i is copied into ci int j = ci; // ok:the value in ci is copied into j By Default, const Objects Are Local to a File When we really need to share const between files, define a single instance of a const variable, we use the keyword extern on both its definition and declaration(s). // file_1.cc defines and initializes a const that is accessible to other files extern const int bufSize = fcn(); // file_1.h extern const int bufSize; // same bufSize as defined in file_1.cc References to const const int ci = 102...