There are at least three semi-independent topics here.
First, the pointer. Pointer is a type that has two primary properties:
1. The value stored by a pointer object is a memory address.
2. Pointer has dereference operator that allows accessing an object at a memory address.
Example:
1 2 3
|
int foo {42};
int * bar {&foo};
std::cout << *bar; // same as std::cout << foo;
|
Both raw pointers and smart pointers are pointers.
Pointers allow indirection. Crude example:
1 2 3 4 5 6 7 8 9 10
|
int gaz( int lhs, int rhs, bool left ) {
int result {nullptr};
if ( left ) {
result = &lhs;
} else {
result = &rhs;
}
// do something with *result
return *result;
}
|
Then the
new
:
This is dynamic memory allocation. A "normal variable" object is allocated statically from stack memory and has lifetime of its enclosing scope. Dynamic allocation creates object in free store memory and object remains alive until it is explicitly destructed. Like the pointer indirection example, we usually do not know during compilation whether user input will demand creation of one Cat or nine Dogs, so static allocation is not possible. Furthermore, the free store has more memory than the stack on most systems, so big data has to use free store.
The
new
,
std::make_unique
and
std::vector
all do dynamic allocation. The crucial difference is in how the deallocation has to (or will) be invoked.
using pointers with classes |
Red herring. The C++ language does not have many types and they are all simple. The class syntax allows definition of additional (more complex) types. Classes are not special; they are just types The more proper question is thus: "
using pointers with types".
The features of pointers gives a part of the answer.
The memory address of dynamically allocated object is not known during compilation. The address is determined when the program is running. There is no way to access the object, unless the address is stored somehow.
The others have already mentioned the polymorphism. When a type is defined not from scratch but by reusing and expanding existing type definition (the class inheritance syntax), then the types have special relation that can be exploited.
The C++ Standard Library provides a collection of useful class definitions, so the users do not have to do everything themselves.
Animal *pCat = new Animal();
Declare a (static) pointer variable.
Initialize the variable with the address of dynamically allocated object.
Construct an Animal object with its default constructor within the dynamically allocated memory.