c++ 引用(reference)和指针 (pointer)

c++ 引用(reference)和指针 (pointer)

Reference

A reference defines an alternative name for an object.

A reference type “refers to” another type. We define a reference type by writing a declarator of the form &d, where d is the name being declared:

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

Ordinarily, when we initialize a variable, the value of the initializer is copied into the object we are creating.

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.

Note:
A reference is not an object. Instead, a reference is just another name for an already existing object.

After a reference has been defined, all operations on that reference are actually operations on the object to which the reference is bound.

Because references are not objects, we may not define a reference to a reference.

Rules:

  1. the type of a reference and the object to which the reference refers must match exactly.

There are two exceptions to the rule that the type of a reference must match the type of the object to which it refers:
References to const

  1. 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

A pointer is a compound type that “points to” another type.

Like references, pointers are used for indirect access to other objects.

Unlike a reference, a pointer is an object in its own right.
Pointers can be assigned and copied; a single pointer can point to
several different objects over its lifetime.

Unlike a reference, a pointer need not be initialized at the time it is defined.

Like other built-in types, pointers defined at block
scope have undefined value if they are not initialized.

Note:
Because references are not objects, they don’t have addresses. Hence, we may not define a pointer to a reference.

Null Pointers

A null pointer does not point to any object. Code can check whether a pointer is null before attempting to use it.

There are several ways to obtain a null pointer:

int *p1 = nullptr; // 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;

The most direct approach is to initialize the pointer using the literal nullptr, which was introduced by the new standard.

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

Alternatively, we can initialize a pointer to the literal 0, as we do in the definition of p2.

Older programs sometimes use a preprocessor variable named NULL, which the cstdlib header defines as 0.

The preprocessor is a program that runs before the compiler.

Preprocessor variables are managed by the preprocessor, and are not part of the std namespace. As a result, we refer to them directly without the std:: prefix.

When we use a preprocessor variable, the preprocessor automatically replaces the variable by its value.

Hence, initializing a pointer to NULL is equivalent to initializing it
to 0.

Modern C++ 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

Advice: Initialize all Pointers

If there is no object to bind to a pointer, then initialize the pointer to nullptr or zero. That way, the program can detect that the pointer does not point to an object.

void* Pointers

The type void* is a special pointer type that can 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:

Rules:

  1. We can compare it to another pointer.
  2. We can pass it to or return it from a function.
  3. We can assign it to another void* pointer.
  4. 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.

Generally, we use a void* pointer to deal with memory as memory, rather than using the pointer to access the object stored in that memory.

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. The rest of the declarator determines the type to which r refers.

The next symbol, * in this case, says that the type r refers to is a pointer type.

Finally, the base type of the declaration says that r is a reference to a pointer to an int.

发布了120 篇原创文章 · 获赞 2 · 访问量 5779

猜你喜欢

转载自blog.csdn.net/Lee567/article/details/104081423