Smart Pointers¶
In C++, a smart pointer is a way of correctly dealing with the memory management issues that can occur when using malloc
or new
. On initialization, smart points will allocate the requested amount of memory, and on destruction they will automatically free that memory. A basic smart pointer is shown in the example below:
template <class TYPE>
class SmartPointer {
public:
TYPE *ptr;
SmartPointer(size_t size){
ptr = new TYPE[size];
}
~SmartPointer(){
delete ptr;
}
};
Using the method above you have to access the raw pointer using the smart_pointer.ptr
method. This can be improved using the example shown below:
template <class TYPE>
class SmartPtr {
TYPE *ptr; // Actual pointer
public:
explicit SmartPtr(TYPE* p = NULL) { ptr = p; }
// Destructor
~SmartPtr() { delete (ptr); }
// Overloading dereferencing operator
TYPE& operator*() { return *ptr; }
};
However, we shouldn’t be rolling our own smart pointer as the memory
library provides us with more fully featured smart pointer options as part of the C++ standard.
Unique Pointers¶
Description¶
Extract from the C++ documentation:
std::unique_ptr
is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.The object is disposed of, using the associated deleter when either of the following happens:
the managing unique_ptr object is destroyed
the managing unique_ptr object is assigned another pointer via
operator=
orreset()
.The object is disposed of, using a potentially user-supplied deleter by calling
get_deleter()(ptr)
. The default deleter uses the delete operator, which destroys the object and deallocates the memory.
Allocation¶
Create a pointer to an integer:
std::unique_ptr<int> p(new int);
Create a pointer to an array of ten integers:
std::unique_ptr<int> p(new int[10])
Allocate a custom object:
class MyObject{
public:
int val;
MyObject(int _val){
val = _val;
std::cout << "Object Created" << std::endl;
}
~MyObject(){
std::cout << val << std::endl;
std::cout << "Object Destroyed" << std::endl;
}
};
int main(){
std::unique_ptr<MyObject> p(new MyObject(4));
}
The above would create the following console output
Object Created
4
Object Destroyed
Unique pointers are the best way of replacing the standard malloc
or new
, and is supported by all modern C++ versions.
Using Unique Pointers¶
Unique pointers do not act like regular pointers when passing them to other functions. However, they support the same in-line operations as objects the hold. The following shows an example of how to use unique pointers:
#include <iostream>
#include <memory>
class MyObject{
public:
int val;
MyObject(int _val){
val = _val;
std::cout << "Object Created" << std::endl;
}
~MyObject(){
std::cout << val << std::endl;
std::cout << "Object Destroyed" << std::endl;
}
};
void PrintObject(MyObject *obj){
std::cout << obj->val << std::endl;
}
int main(){
std::unique_ptr<MyObject> p(new MyObject(4));
/* Print the MyObject value */
PrintObject(p.get());
/* Change the MyObject value */
p->val = 5;
return 0;
}
This will return the following:
Object Created
4
5
Object Destroyed