unique_ptr& operator=( unique_ptr<U,E>&& r ) noexcept;
If Deleter is not a reference type, requires that it is nothrow- MoveAssignable . If Deleter is a reference type, requires that std:: remove_reference < Deleter > :: type is nothrow- CopyAssignable .
Note that unique_ptr 's assignment operator only accepts rvalues , which are typically generated by std::move . (The unique_ptr class explicitly deletes its lvalue copy constructor and lvalue assignment operator.)
Parameters Return value Example Defect reports |
r | - | smart pointer from which ownership will be transferred |
[ edit ] example, [ edit ] defect reports.
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
C++11 | rejected qualification conversions | accepts | |
C++11 | the converting assignment operator was not constrained | constrained | |
C++11 | the move assignment operator was not constrained | constrained |
The compiler is given a lot of flexibility in terms of how it handles this call. It could create a new T, then call function_that_can_throw_exception(), then create the std::unique_ptr that manages the dynamically allocated T. If function_that_can_throw_exception() throws an exception, then the T that was allocated will not be deallocated, because the smart pointer to do the deallocation hasn’t been created yet. This leads to T being leaked.
In the above code, createResource() returns a std::unique_ptr by value. If this value is not assigned to anything, the temporary return value will go out of scope and the Resource will be cleaned up. If it is assigned (as shown in main()), in C++14 or earlier, move semantics will be employed to transfer the Resource from the return value to the object assigned to (in the above example, ptr), and in C++17 or newer, the return will be elided. This makes returning a resource by std::unique_ptr much safer than returning raw pointers!
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Stores a pointer to an owned object or array. The object/array is owned by no other unique_ptr . The object/array is destroyed when the unique_ptr is destroyed.
Right A unique_ptr .
Nptr An rvalue of type std::nullptr_t .
Ptr A pointer .
Deleter A deleter function that is bound to a unique_ptr .
No exceptions are generated by unique_ptr .
The unique_ptr class supersedes auto_ptr , and can be used as an element of C++ Standard Library containers.
Use the make_unique helper function to efficiently create new instances of unique_ptr .
unique_ptr uniquely manages a resource. Each unique_ptr object stores a pointer to the object that it owns or stores a null pointer. A resource can be owned by no more than one unique_ptr object; when a unique_ptr object that owns a particular resource is destroyed, the resource is freed. A unique_ptr object may be moved, but not copied; for more information, see Rvalue Reference Declarator: && .
The resource is freed by calling a stored deleter object of type Del that knows how resources are allocated for a particular unique_ptr . The default deleter default_delete<T> assumes that the resource pointed to by ptr is allocated with new , and that it can be freed by calling delete _Ptr . (A partial specialization unique_ptr<T[]> manages array objects allocated with new[] , and has the default deleter default_delete<T[]> , specialized to call delete[] ptr .)
The stored pointer to an owned resource, stored_ptr has type pointer . It's Del::pointer if defined, and T * if not. The stored deleter object stored_deleter occupies no space in the object if the deleter is stateless. Note that Del can be a reference type.
Name | Description |
---|---|
There are seven constructors for . |
Name | Description |
---|---|
A synonym for the template parameter . | |
A synonym for the template parameter . | |
A synonym for if defined, otherwise . |
Name | Description |
---|---|
Returns . | |
Returns a reference to . | |
stores in and returns its previous contents. | |
Releases the currently owned resource and accepts a new resource. | |
Exchanges resource and with the provided . |
Name | Description |
---|---|
The operator returns a value of a type that is convertible to . The result of the conversion to is when , otherwise . | |
The member function returns . | |
The member function returns . | |
Assigns the value of a (or a ) to the current . |
The type is a synonym for the template parameter Del .
The type is a synonym for the template parameter Type .
The type is a synonym for the template parameter Ty .
Returns stored_ptr .
The member function returns stored_ptr .
Returns a reference to stored_deleter .
The member function returns a reference to stored_deleter .
Assigns the address of the provided unique_ptr to the current one.
A unique_ptr reference used to assign the value of to the current unique_ptr .
The member functions call reset(right.release()) and move right.stored_deleter to stored_deleter , then return *this .
A synonym for Del::pointer if defined, otherwise Type * .
The type is a synonym for Del::pointer if defined, otherwise Type * .
Releases ownership of the returned stored pointer to the caller and sets the stored pointer value to nullptr .
Use release to take over ownership of the raw pointer stored by the unique_ptr . The caller is responsible for deletion of the returned pointer. The unique-ptr is set to the empty default-constructed state. You can assign another pointer of compatible type to the unique_ptr after the call to release .
This example shows how the caller of release is responsible for the object returned:
Takes ownership of the pointer parameter, and then deletes the original stored pointer. If the new pointer is the same as the original stored pointer, reset deletes the pointer and sets the stored pointer to nullptr .
ptr A pointer to the resource to take ownership of.
Use reset to change the stored pointer owned by the unique_ptr to ptr and then delete the original stored pointer. If the unique_ptr wasn't empty, reset invokes the deleter function returned by get_deleter on the original stored pointer.
Because reset first stores the new pointer ptr , and then deletes the original stored pointer, it's possible for reset to immediately delete ptr if it's the same as the original stored pointer.
Exchanges pointers between two unique_ptr objects.
right A unique_ptr used to swap pointers.
The member function swaps stored_ptr with right.stored_ptr and stored_deleter with right.stored_deleter .
There are seven constructors for unique_ptr .
ptr A pointer to the resource to be assigned to a unique_ptr .
_Deleter A deleter to be assigned to a unique_ptr .
right An rvalue reference to a unique_ptr from which unique_ptr fields are move assigned to the newly constructed unique_ptr .
The first two constructors construct an object that manages no resource. The third constructor stores ptr in stored_ptr . The fourth constructor stores ptr in stored_ptr and deleter in stored_deleter .
The fifth constructor stores ptr in stored_ptr and moves deleter into stored_deleter . The sixth and seventh constructors store right.release() in stored_ptr and moves right.get_deleter() into stored_deleter .
The destructor for unique_ptr , destroys a unique_ptr object.
The destructor calls get_deleter()(stored_ptr) .
Was this page helpful?
The smart pointers are a really good mechanism to manage dynamically allocated resources. In this article, we will see unique_ptr with example in C++11. But we don’t discuss standard smart pointers from a library. Rather, we implement our own smart pointer equivalent to it. This will give us an idea of inside working of smart pointers.
Prior to C++11, the standard provided std::auto_ptr . Which had some limitations. But from C++11, standard provided many smart pointers classes. Understanding unique_ptr with example in C++ requires an understanding of move semantics which I have discussed here & here .
But before all these nuisances, we will see “Why do we need smart pointer in 1st place?”:
func() { Resource *ptr = new Resource; int x; std::cout << "Enter an integer: "; std::cin >> x; if (x == 0) throw 0; // the function returns early, and ptr won't be deleted! if (x < 0) return; // the function returns early, and ptr won't be deleted! // do stuff with ptr here delete ptr; } |
<class T> class smart_ptr { T* m_ptr; public: smart_ptr(T* ptr=nullptr):m_ptr(ptr){} ~smart_ptr() { delete m_ptr; } T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } }; |
Resource { public: Resource() { std::cout << "Resource acquired\n"; } ~Resource() { std::cout << "Resource destroyed\n"; } }; void func() { smart_ptr<Resource> ptr(new Resource); // ptr now owns the Resource int x; std::cout << "Enter an integer: "; std::cin >> x; if (x == 0) throw 0; if (x < 0) return; // do stuff with ptr here // dont care about deallocation } int main() { try{ func(); } catch(int val){} return 0; } |
Hi! Resource destroyed |
main() { smart_ptr<Resource> res1(new Resource); smart_ptr<Resource> res2(res1); // Alternatively, don't initialize res2 and then assign res2 = res1; return 0; } |
Resource destroyed Resource destroyed |
<class T> class smart_ptr { T* m_ptr; public: smart_ptr(T* ptr=nullptr) :m_ptr(ptr) {} ~smart_ptr() { delete m_ptr; } // copy constructor that implements move semantics smart_ptr(smart_ptr& a) // note: not const { m_ptr = a.m_ptr; // transfer our dumb pointer from the source to our local object a.m_ptr = nullptr; // make sure the source no longer owns the pointer } // assignment operator that implements move semantics smart_ptr& operator=(smart_ptr& a) // note: not const { if (&a == this) return *this; delete m_ptr; // make sure we deallocate any pointer the destination is already holding first m_ptr = a.m_ptr; // then transfer our dumb pointer from the source to the local object a.m_ptr = nullptr; // make sure the source no longer owns the pointer return *this; } T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } }; class Resource { public: Resource() { std::cout << "Resource acquired\n"; } ~Resource() { std::cout << "Resource destroyed\n"; } }; int main() { smart_ptr<Resource> res1(new Resource); smart_ptr<Resource> res2(res1); return 0; } |
Resource destroyed |
<class T> class smart_ptr { T* m_ptr; public: smart_ptr(T* ptr = nullptr) : m_ptr(ptr){} ~smart_ptr() { delete m_ptr; } // Copy constructor smart_ptr(const smart_ptr& a) = delete; // Move constructor smart_ptr(smart_ptr&& a) : m_ptr(a.m_ptr) { a.m_ptr = nullptr; } // Copy assignment smart_ptr& operator=(const smart_ptr& a) = delete; // Move assignment smart_ptr& operator=(smart_ptr&& a) { if (&a == this) return *this; delete m_ptr; m_ptr = a.m_ptr; a.m_ptr = nullptr; return *this; } T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } }; class Resource { public: Resource() { std::cout << "Resource acquired\n"; } ~Resource() { std::cout << "Resource destroyed\n"; } }; smart_ptr<Resource> func(smart_ptr<Resource> temp) { // Do something return temp; } int main() { smart_ptr<Resource> res1(new Resource); // smart_ptr<Resource> res3 = res1; // Won't compile, as copy contructor is deleted smart_ptr<Resource> res3 = func(std::move(res1)); // calls move semantics return 0; } |
Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
I just finished learning about move semantics and realized that a nice practical example for this concept is unique_ptr (it cannot be copied, only moved).
For learning purposes, and as a personal experiment, I proceed to try to create my implementation for a smart unique pointer:
For a small set of test cases, this is working like the real unique_ptr .
However, it just seems too simple enough.
I have two questions regarding this code:
Is it well-formed?
It compiles, so yes.
i.e. does it follow common C++ standard and patterns (for example, should private members be declared before public ones?
Personally I think so.
When reading the code I want to know the members so I can verify that the constructors initialize them all, as a result I usually put them first. But other people prefer to put all private stuff at the bottom.
Am I missing something regarding functionality?
Yes. Quite a lot.
Is there maybe a bug in my code that I'm not seeing?
Yes. It potentially leaks on assignment.
Constructing from object.
That's exceedingly dangerous:
You should always attempt to use the member initializer list for initializing members. Any non-trivial object will have its constructor called before the initializer code is called and thus it is inefficient to then re-initialize it in the code.
Prefer not to use _ as the first character in an identifier name.
Even if you know all the rules of when to use them most people don't so they are best avoided. If you must have a prefix to identify members use m_ - but if you name your member variables well then there is no need for any prefix (in my opinion prefixes makes the code worse not better, because you are relying on unwritten rules. If you have good well-defined names (see self-documenting code) then members should be obvious).
The move operators should be marked as noexcept .
When used with standard containers this will enable certain optimizations. This is because if the move is noexcept then certain operations can be guaranteed to work and thus provide the strong exception guarantee.
Note: Your current assignment potentially leaks. If this currently has a pointer assigned then you overwrite it without freeing.
Yes you do need to make it work when there is self assignment. But in real code the self assignment happens so infrequently that this test becomes a pessimization on the normal case (same applies for copy operation). There have been studies on this (please somebody post a link; I have lost mine and would like to add it back to my notes).
The standard way of implementing move is via swap. Just like Copy is normally implemented by Copy and Swap.
Using the swap technique also delays the calling of the destructor on the pointer for the current object. Which means that it can potentially be re-used. But if it is going out of scope the unique_ptr destructor will correctly destroy it.
Good first try but still lots of issues.
Please read the article I wrote on unique_ptr and shared_ptr for lots more things you should implement.
Smart-Pointer - Unique Pointer Smart-Pointer - Shared Pointer Smart-Pointer - Constructors
Some things you missed:
When you have read all three articles then the bare bones unique_ptr looks like this:
Test to make sure it compiles:
Yes, have good formatting
I have the same thought present in Martin York' answer:
Yes, you forgot to add T, and T[], and the following features:
type* release();
void reset(type* item);
void swap(unique_ptr &other);
type* get();
operator->;
operator[];
Yes, you must force the receiving of types strictly to be pointers
This is redundant, this part is not necessary as this operator will never be called taking into account that the motion constructor exists and the copy constructor is disabled (= delete).
You must accept both types T, and T[], ie: array or not.
Verify in move assignment operator.
Before _ptr =, you need to check if this->ptr is initialized, if yes delete ptr before assign.
This above code is incorrect, this is pointer and uptr is reference, you need to add &other to verify successfully
Note: std::move in uptr._ptr is irrelevant.
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .
non-specialized | |
---|---|
array specialization |
Member types.
member type | definition | notes |
---|---|---|
first template parameter ( ) | The type of the managed object | |
second template parameter ( ) | The type of the . Defaults to <T> | |
, if this type exists , otherwise | The pointer type |
Non-member function overloads.
std::unique_ptr is a smart pointer introduced in C++11. It automatically manages the dynamically allocated resources on the heap. Smart pointers are just wrappers around regular old pointers that help you prevent widespread bugs. Namely, forgetting to delete a pointer and causing a memory leak or accidentally deleting a pointer twice or in the wrong way. They can be used in a similar way to standard pointers. They automate some of the manual processes that cause common bugs.
Prerequisites: Pointer in C++ , Smart Pointers in C++.
When we write unique_ptr<A> ptr1 (new A), memory is allocated on the heap for an instance of datatype A. ptr1 is initialized and points to newly created A object. Here, ptr1 is the only owner of the newly created object A and it manages this object’s lifetime. This means that when ptr1 is reset or goes out of scope, memory is automatically deallocated and A’s object is destroyed.
When ownership of resource is required. When we want single or exclusive ownership of a resource, then we should go for unique pointers. Only one unique pointer can point to one resource. So, one unique pointer cannot be copied to another. Also, it facilitates automatic cleanup when dynamically allocated objects go out of scope and helps preventing memory leaks.
Note: We need to use the <memory> header file for using these smart pointers.
Lets create a structure A and it will have a method named printA to display some text. Then in the main section, let’s create a unique pointer that will point to the structure A. So at this point, we have an instance of structure A and p1 holds the pointer to that.
Now let’s create another pointer p2 and we will try to copy the pointer p1 using the assignment operator(=).
The above code will give compile time error as we cannot assign pointer p2 to p1 in case of unique pointers. We have to use the move semantics for such purpose as shown below.
Managing object of type A using move semantics.
Note once the address in pointer p1 is copied to pointer p2, the pointer p1’s address becomes NULL(0) and the address stored by p2 is now the same as the address stored by p1 showing that the address in p1 has been transferred to the pointer p2 using the move semantics.
Similar reads.
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Get early access and see previews of new features.
I have a problem very similar to
How to make a class with a member of unique_ptr work with std::move and std::swap?
and I am using VS2013 so I expect the following to work.
path\engine.cpp(75): error C2280: 'std::unique_ptr> &std::unique_ptr<_Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function with [ _Ty=AbstractCamera ] other_path\memory(1487) : see declaration of 'std::unique_ptr>::operator =' with [ _Ty=AbstractCamera ] This diagnostic occurred in the compiler generated function 'RenderManager &RenderManager::operator =(const RenderManager &)'
I do get that simple examples like
are not allowed but my problem is the following code:
because the assignment operator of unique_ptr is deleted but how does this affect a class hierarchy like those of Engine->RenderManger->unique_ptr member.
I do get, that Engine e uses the default constructor Engine() and e = Engine() calls the default constructor and the operator= of Engine to assign the temporary Engine object to e.
My question therefore is: where does the code try to copy/assign unique_ptr and how do I resolve it?
I tried to strip the original code down as much as possible but was not able to reproduce the error using a simpler example and ideone in form of a SSCCEE as I do not really understand what causes the problem, so sorry for that!
VS2013 does not automatically generate move special member functions (this is non-conforming, in case it isn't obvious). You'll have to write the move constructor and move assignment operator of Engine and RenderManager yourself, as otherwise the copy special member functions will be used.
As a side note, _currentCamera(std::move(std::make_unique<CameraImpl>)) won't compile; _currentCamera(std::move(std::make_unique<CameraImpl>())) would but the std::move is useless and a pessimization. make_unique already returns an rvalue. There are also several other typos in your code, presumably caused by the minimization process.
T.C. correctly answered the question, but I wanted to give some further insights as I did actually asked the wrong question :)
The real question therefore should have been
How can I use the following code
when my intent is the destruction of the default constructed object e and the assignment of the newly constructed object.
First of all one needs to understand the difference between copy and move assignment and construction and the following thread and especially the two long posts by @FredOverflow here can help very much to understand this: What are move semantics?
The problem setting are actually classes with std::vectors<std::unique_ptr<T>> and classes with std::unique_ptr<T> members. See http://www.cplusplus.com/forum/beginner/110610/ and the answer of JLJorges for a longer example.
JLJorges posted:
So don't do anything: by default B is not Copyable or Assignable, but B is Moveable and MoveAssignable
JLJorges pointed out two important things under such circumstances:
VS2013 therefore is able to implicitly generate move and move assign operators/constructors as it does exactly this for such a class setup.
The reason I did not select T.C.'s answer altough he was very helpful and close to the answer is the following:
In case one needs copy-able/copy-assignable classes he has to implement copy-constructor and copy-assignment . This would have been the answer if I would have needed exactly what the code in the initial question looked like: a copy/copy-assignable class Engine.
In case one implements one of those methods/operators he might want to implement the others as well, see the following links for explanations:
As I said, I had the asked the wrong question, as I did not needed a copyable/copyassignable class the solution would have been to implement move constructor and move assign operator or like JLJorges pointed out: do nothing and use the implicitly generated version, but when I wanted to move I obviously had to tell the compiler this:
e = Engine() calls Engine's move assignment operator. Since you don't have one, it's copy assignment operator will be called. Then RenderManger's copy assignment will be called. Finally it's the copy assignment of unique_ptr, which is deleted.
A move assignment is needed for Engine, as
Engine & operator = (Engine && rhs) { r._currentCamera = std::move(rhs.r._currentCamera); return * this; }
Suppose RenderManager::_currentCamera is visible to Engine, otherwise you need to defind move assignment for RenderManager.
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .
COMMENTS
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= or reset().
Given the common situation where the lifespan of an owned object is linked to its owner, I can use a unique pointer one of 2 ways . . It can be assigned: std::unique_ptr<someObject> owned; owner() owned=std::unique_ptr<someObject>(new someObject()); The reset method can be utilised:
a stored deleter: a callable object that takes an argument of the same type as the stored pointer and is called to delete the managed object. It is set on construction, can be altered by an assignment operation, and can be individually accessed using member get_deleter. unique_ptr objects replicate a limited pointer functionality by providing ...
In this article. 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. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it.
Constructs a unique_ptr object, depending on the signature used: default constructor (1), and (2) The object is empty (owns nothing), with value-initialized stored pointer and stored deleter. construct from pointer (3) The object takes ownership of p, initializing its stored pointer to p and value-initializing its stored deleter. construct from pointer + lvalue deleter (4)
For the array specialization (unique_ptr<T[]>), this overload participates in overload resolution only if U is an array type, ... As a move-only type, unique_ptr's assignment operator only accepts rvalues arguments (e.g. the result of std::make_unique or a std::move 'd unique_ptr variable).
2) Constructs a std::unique_ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter. Requires that Deleter is DefaultConstructible and that construction does not throw an exception. This overload participates in overload resolution only if std:: is_default_constructible < Deleter >:: value is true and Deleter is not a pointer type.
This assignment operator in the specialization for arrays, std::unique_ptr<T[]> behaves the same as in the primary template, except that will only participate in overload resolution if all of the following is true: U is an array type. pointer is the same type as element_type*. unique_ptr<U,E>::pointer is the same type as unique_ptr<U,E ...
std::unique_ptr is by far the most used smart pointer class, so we'll cover that one first. In the following lessons, we'll cover std::shared_ptr and std::weak_ptr. std::unique_ptr. std::unique_ptr is the C++11 replacement for std::auto_ptr. It should be used to manage any dynamically allocated object that is not shared by multiple objects.
The assignment operation between unique_ptr objects that point to different types (3) needs to be between types whose pointers are implicitly convertible, and shall not involve arrays in any case (the third signature is not part of the array specialization of unique_ptr). Copy assignment (4) to a unique_ptr type is not allowed (deleted signature).
unique_ptr uniquely manages a resource. Each unique_ptr object stores a pointer to the object that it owns or stores a null pointer. A resource can be owned by no more than one unique_ptr object; when a unique_ptr object that owns a particular resource is destroyed, the resource is freed. A unique_ptr object may be moved, but not copied; for ...
The proper way to do this is with the std::move standard library function. If you take a unique_ptr by value, you can move from it freely. But movement doesn't actually happen because of std::move. Take the following statement: std::unique_ptr<Base> newPtr(std::move(oldPtr)); This is really two statements:
std::auto_ptr, and why to avoid it#. What we have seen above as smart_ptr is basically an std::auto_ptr which was introduced in C++98, was C++'s first attempt at a standardized smart pointer.; However, std::auto_ptr (and our smart_ptr class) has a number of problems that make using it dangerous. Because std::auto_ptr implements move semantics through the copy constructor and assignment ...
Return value (none) [] NoteTo replace the managed object while supplying a new deleter as well, move assignment operator may be used. A test for self-reset, i.e. whether ptr points to an object already managed by * this, is not performed, except where provided as a compiler extension or as a debugging assert.Note that code such as p. reset (p. release ()) does not involve self-reset, only code ...
Copy assignment operator unique_ptr<T>& operator=(const unique_ptr<T>& uptr) = delete; This is redundant, this part is not necessary as this operator will never be called taking into account that the motion constructor exists and the copy constructor is disabled (= delete).
a stored deleter: a callable object that takes an argument of the same type as the stored pointer and is called to delete the managed object. It is set on construction, can be altered by an assignment operation, and can be individually accessed using member get_deleter. unique_ptr objects replicate a limited pointer functionality by providing ...
Then, the operator= is only defined for rvalue references of unique pointers and not raw pointers, and a raw pointer cannot be implicitly converted to a smart pointer, to avoid accidental assignment that breaks uniqueness. Therefore a raw pointer cannot be directly assigned to it. The correct approach is put it to the constructor: std::unique_ptr<int[]> ptr (new int[3]); // ^^^^^
pointer operator->()constnoexcept; (2) (since C++11)(constexpr since C++23) operator* and operator-> provide access to the object owned by *this . The behavior is undefined if get()== nullptr . These member functions are only provided for unique_ptr for the single objects i.e. the primary template.
std::unique_ptr is a smart pointer introduced in C++11. It automatically manages the dynamically allocated resources on the heap. Smart pointers are just wrappers around regular old pointers that help you prevent widespread bugs. Namely, forgetting to delete a pointer and causing a memory leak or accidentally deleting a pointer twice or in the ...
Please also note that if you did succeed in having unique_ptr<const Foo>& getFoo(), the caller could do mfoo.getFoo().reset(new Foo(42)), replacing the whole Foo object our from under the ManageFoo. Pointer-to-const is not the same as a const pointer, and that remains true for smart pointers. -
unique_ptr should be used with std::move semantics, and the copy assignment operator was explicitly removed for lvalues, so that anything like. unique_ptr<int> r = another_unique_ptr; will not work. I found the following signatures on cpp reference: unique_ptr& operator=( unique_ptr&& r ); (1) template< class U, class E >.
e = Engine() calls Engine's move assignment operator. Since you don't have one, it's copy assignment operator will be called. Then RenderManger's copy assignment will be called. Finally it's the copy assignment of unique_ptr, which is deleted. A move assignment is needed for Engine, as. Engine & operator = (Engine && rhs) {.