Search code examples
c++oopunique-ptrdeque

push objects in vector of class when class has a deque of unique_ptr


I am somewhat new to using unique_ptr and was using it in some of my code. While trying to use unique_ptr, I have the following code which doesn't seem to work, could anyone explain me why?

#include <vector>
#include <deque>
#include <memory>

class MyClass {
public:
    MyClass(int x) {
        myDeque.push_back(std::unique_ptr<int>(new int(x)));
    }
private:
    std::deque<std::unique_ptr<int>> myDeque;
};

int main() {
    std::vector<MyClass> myVector;
    myVector.push_back(MyClass(5));
}

I wish to have a deque of unique_ptr in a class and would populate it from another function, and I also need to have a vector of class objects of MyClass. The code works when I make myDeque global but throws error when it is a member variable.


Solution

  • If MyClass has move only members (like unique_ptr) whole class can be move only. To achieve it delete copy constructor and assign operator and define move constructor and assign operator.

    class MyClass {
    public:
        MyClass(int x) {
            myDeque.push_back(std::make_unique<int>(x));
        }
        MyClass(MyClass&&) = default;//move constructor 
        MyClass& operator=(MyClass&&) =default;//move assign operator 
    private:
        MyClass(const MyClass&) = delete;// prevents creating copy
        MyClass& operator=(const MyClass&) = delete;// prevents creating copy
        std::deque<std::unique_ptr<int>> myDeque;
    };
    

    And remember to use std::move if you push lvalue to vector

    int main() {
        std::vector<MyClass> myVector;
        MyClass q(5);
        myVector.push_back(std::move(q));// since q is lvalue std::move required
        myVector.push_back(MyClass(6));
    }
    

    If you want to create copies of MyClass define proper copy constructor and copy assign operator where you not trying to copy unique_ptr but only its dereferenced value:

    MyClass(const MyClass& to_copy) {
            size_t copy_size = to_copy.myDeque.size();
            for (size_t i = 0; i < copy_size; i++)
            {
                this->myDeque.push_back(std::make_unique<int>(*to_copy.myDeque[i]));
            }
        }