Is this code fragment valid? :
unique_ptr<A> p(new A());
p = nullptr;
That is, can I assign nullptr
to a unique_ptr
? or it will fail?
I tried this with the g++ compiler and it worked, but what about other compilers?
nullptr is a keyword new in C++11 for better support of null pointers. unique_ptr can be constructed from nullptr , even implicitly.
The unique_ptr shall not be empty (i.e., its stored pointer shall not be a null pointer) in order to be dereferenciable. This can easily be checked by casting the unique_ptr object to bool (see unique_ptr::operator bool). It is equivalent to: *get().
A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.
It will work.
From Paragraphs 20.7.1.2.3/8-9 of the C++11 Standard about the unique_ptr<>
class template:
unique_ptr& operator=(nullptr_t) noexcept
;Effects:
reset()
.Postcondition:
get() == nullptr
This means that the definition of class template unique_ptr<>
includes an overload of operator =
that accepts a value of type nullptr_t
(such as nullptr
) as its right hand side; the paragraph also specifies that assigning nullptr
to a unique_ptr
is equivalent to resetting the unique_ptr
.
Thus, after this assignment, your A
object will be destroyed.
More common case:
#include <iostream>
#include <string>
#include <memory>
class A {
public:
A() {std::cout << "A::A()" << std::endl;}
~A() {std::cout << "A::~A()" << std::endl;}
};
class B {
public:
std::unique_ptr<A> pA;
B() {std::cout << "B::B()" << std::endl;}
~B() { std::cout << "B::~B()" << std::endl;}
};
int main()
{
std::unique_ptr<A> p1(new A());
B b;
b.pA = std::move(p1);
}
Output:
A::A()
B::B()
B::~B()
A::~A()
This code example can be non-intuitive:
#include <iostream>
#include <string>
#include <memory>
class A {
public:
A() {std::cout << "A::A()" << std::endl;}
~A() {std::cout << "A::~A()" << std::endl;}
};
class B {
public:
std::unique_ptr<A> pA;
B() {std::cout << "B::B()" << std::endl;}
~B()
{
if (pA)
{
std::cout << "pA not nullptr!" << std::endl;
pA = nullptr; // Will call A::~A()
}
std::cout << "B::~B()" << std::endl;
}
};
int main()
{
std::unique_ptr<A> p1(new A());
B b;
b.pA = std::move(p1);
}
Output:
A::A()
B::B()
pA not nullptr!
A::~A()
B::~B()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With