This blog was last modified 328 days before.
There are three different types of smart pointers in C++.
- unique_ptr
- shared_ptr
- weak_ptr
Checkout Microsoft Learn - Smart Pointers for basics of this smart pointer class.
Init Smart Pointers
In Microsoft Learn, it widely use the following patterns:
make_unique<T> pValue(new T(...));
In this case, it's ok, but consider the following situation:
// func declaration
func(unique_ptr<T> pValue1, unique_ptr<T> pValue1);
// call func()
func(unique_ptr<T>(new T(1)), unique_ptr<T>(new T(2)));
Looks great. But what if one of the allocation (new T(1)
or new T(2)
) failed? This may lead to memory leak. For more info, check out this Question on StackOverflow.
make_unique
To avoid memory leak in some specified cases, we should use make_unique()
instead:
auto pValue = make_unique<T>(T());
Notice that this time we don't need to use new
keyword anymore.
Convertion between pointers
We mainly talking about unique_ptr
and smart_ptr
. Generally we have:
-
unique_ptr
->shared_ptr
(Allowed) -
shared_ptr
->unique_ptr
(Not Allowed)
This behaviour concur with intuitives, because sinces shared_ptr
could be shared in different scope and even in different threads, it's nearly impossible to transfer its whole ownership.
To convert a unique_ptr to shared_ptr, we need to give up the ownership of the unique_ptr
and move it to a compatible type shared_ptr:
// create unique_ptr
unique_ptr<int> pValue = make_unique<int>();
// transfer ownership to a shared_ptr object
shared_ptr<int> pShared(std::move(pValue));
*pValue; // Don't do this, pValue is invalid here! Use pShared instead.
Code example:
#include <iostream>
#include <memory>
using std::cout, std::endl, std::move;
using std::make_unique, std::make_shared;
using std::unique_ptr, std::shared_ptr, std::weak_ptr;
int main()
{
auto pValue = make_unique<int>(100);
shared_ptr<int> pShared(std::move(pValue));
cout << *pShared << endl; // Output: 100
cout << *pValue << endl; // will cause segment fault.
return 0;
}
No comment