Home > other >  Should I mark the move constructor & move assignment operator as deleted in this case?
Should I mark the move constructor & move assignment operator as deleted in this case?

Time:06-11

I hope to prevent the users from creating new instance through the constructor, so I mark the constructor as a private method.

What's more, I need to provide a method to return an type which is used to automatically manage the life of the instance. I don't hope the user to use the instance of Foo class directly, I hope they always use std::shared_ptr<Foo> instead.

#include <iostream>
#include <memory>
 
class Foo : public std::enable_shared_from_this<Foo> {
private:     //the user should not construct an instance through the constructor below.                    
    Foo(int num):num_(num) { std::cout << "Foo::Foo\n"; }
public:
    Foo(const Foo&) = delete;
    Foo(Foo&&) = default;
    Foo& operator=(const Foo&) = delete;
    Foo& operator=(Foo&&) = default;

public:
    ~Foo() { std::cout << "Foo::~Foo\n"; } 

    int DoSth(){std::cout << "hello world" << std::endl; return 0;}

    std::shared_ptr<Foo> getPtr() { return shared_from_this();}

    static std::shared_ptr<Foo> Create() {
        Foo* foo = new Foo(5);
        return std::shared_ptr<Foo>(foo);
    }

private:
    int num_;

};

int main()
{
    auto sp = Foo::Create();
    sp->DoSth();

    Foo& foo = *sp.get();
    auto sp1 = foo.getPtr();

    Foo foo1(std::move(foo));

    std::cout << sp.use_count() << std::endl;
}

I am not sure whether or not I should mark the move constructor & move assignment operator as deleted.

What I am worried about is that there is a thread safety issue if one thread is invoking move constructor while the other thread is calling some member function at the same time. How do you think about it?

CodePudding user response:

I think your question answers itself.

I don't hope the user to use the instance of Foo class directly, I hope they always use std::shared_ptr<Foo> instead.

followed by

Foo foo1(std::move(foo));

demonstrating the ability to use an instance of Foo directly, not managed by a shared pointer. Defining the move constructor as deleted prevents this thing you want users to avoid.

  • Related