norq
norq

Reputation: 1434

Initialize member class that prohibits copy

I have a member variable that is a class that prohibits copying (copy assignment operator is deleted). I want to make some checks to determine what to initiate the member to, thus I need to do this inside the constructor and not in and initializer list. It seem the member variable m is already initialed with the default constructor before entering the constructor of MyClass, then what is the point of the constructor... sorry for c++ rant.

Simple example:

class MyClass {
    NonCopy m;
    MyClass() {
        // Complex checks
        if(success) {
            m("success");
        else {
            m("failure");
        }

    }

The options I see is:

Upvotes: 1

Views: 108

Answers (2)

NathanOliver
NathanOliver

Reputation: 180630

As long as the class has a valid copy or move constructor, or you are using C++17+, you can make a helper function that does the logic and then returns the correct object. You then use that to initialize your member. That would look like

class MyClass {
    NonCopy m;
    static NonCopy initialize_noncopy()
    {
        // Complex checks
        if(success) {
            return NonCopy("success");
        else {
            return NonCopy("faulure");
        }
    }
public:
    MyClass() : m(initialize_noncopy()) { }
};

Upvotes: 5

HTNW
HTNW

Reputation: 29193

Well, you're supposed to initialize member variables before the constructor body

struct C {
    M member;
    C() : member("some arguments") { }
};

But this only works if you know the arguments for the member's initializer at that time! If you really don't want to initialize member until you get some more information in the constructor body, you can place it into a single-member anonymous union.

struct C {
    union { M member; };
    C() { // member is not initialized
        // do whatever
        new(&member) M("some arguments"); // explicitly initialize
    }
    // now you have to write all the other special functions!
    ~C() { member.~M(); }
    C(C const &x) = delete;
    C(C &&x) { new(&member) M(std::move(x.member)); }
    C &operator=(C const &x) = delete;
    C &operator=(C &&x) { member = std::move(x.member); return *this; }
};

Upvotes: 2

Related Questions