#include <iostream>
int main () {
int first_value, second_value;
int* my_pointer;
my_pointer = &first_value;
*my_pointer = 10;
my_pointer = &second_value;
*my_pointer = 20;
std::cout << "first_value is " << first_value << '\n';
std::cout << "second_value is " << second_value << '\n';
return 0;
}
-
Prints:
first_value is 10
second_value is 20
Creation and initialization
int my_var;
int* my_ptr = &my_var;
// is equivalent to:
int my_var;
int * my_ptr;
my_ptr = &my_var;
int my_var;
int *foo = &my_var;
int *bar = foo;
-
This is incorrect, as it doesn't make sense :
int my_var; int * my_ptr; *my_ptr = &my_var;
Declaring many pointers in a single line
-
Incorrect :
int* p1, p2; -
Correct :
int* p1, * p2;
Null pointers
int* p = 0;
int* q = nullptr;
int* r = NULL;
-
Both
pandqare null pointers, meaning that they explicitly point to nowhere, and they both actually compare equal: all null pointers compare equal to other null pointers. -
NULLis defined in several headers of the standard library, and is defined as an alias of some null pointer constant value (such as0ornullptr).
Operations
-
Only addition and subtraction operations are allowed; the others make no sense in the world of pointers.
-
Both addition and subtraction have a slightly different behavior with pointers, according to the size of the data type to which they point.
-
When adding one to a pointer, the pointer is made to point to the following element of the same type, and, therefore, the size in bytes of the type it points to is added to the pointer.
-
Example :
char* my_char; // example address 1000 short* mys_hort; // example address 2000 long* my_long; // example address 3000 ++my_char; // example address 1001 ++mys_hort; // example address 2002 ++my_long; // example address 3004 -
This is applicable both when adding and subtracting any number to a pointer.
Pointers to constant data and constant pointers
int x;
int* p1 = &x; // non-const pointer to non-const int
const int* p2 = &x; // non-const pointer to const int
int* const p3 = &x; // const pointer to non-const int
const int* const p4 = &x; // const pointer to const int
-
To add a little bit more confusion to the syntax of const with pointers, the const qualifier can either precede or follow the pointed type, with the exact same meaning:
const int* p2a = &x; // non-const pointer to const int
int const* p2b = &x; // also non-const pointer to const int
-
They are pointers that can access the pointed value to read it, but not to modify it.
-
These pointers point to constant content they cannot modify, but they are not constant themselves: i.e., the pointers can still be incremented or assigned different addresses, although they cannot modify the content they point to.
int x;
int y = 10;
const int * p = &y;
x = *p; // ok: reading p
*p = x; // error: modifying p, which is const-qualified
-
A pointer to non-const can be implicitly converted to a pointer to const, but not the other way around.
-
They are usually used for function parameters:
#include <iostream>
void increment_all(int* start, int* stop) {
int * current = start;
while (current != stop) {
++(*current); // increment value pointed
++current; // increment pointer
}
}
void print_all(const int* start, const int* stop) {
const int * current = start;
while (current != stop) {
std::cout << *current << '\n';
++current; // increment pointer
}
}
int main() {
int numbers[] = {10,20,30};
increment_all(numbers, numbers+3);
print_all(numbers, numbers+3);
return 0;
}
std::unique_ptr
-
single owner
-
cannot be copied
-
cheap
-
deterministic lifetime
std::unique_ptr<A> p = std::make_unique<A>();
std::shared_ptr
-
reference counted
-
multiple owners
-
more expensive
std::shared_ptr<A> p1 = std::make_shared<A>();
std::shared_ptr<A> p2 = p1;