1

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:

  • Reside to dynamic allocation of m
  • Relax copy prohibit requirement of m
0

2 Answers 2

5

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()) { } }; 
Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't it be better to move the decision part to a different function, but not the initialization. So, something like MyClass() : m(decide() ? "success" : "failure") { }
@AyxanHaqverdili Depends. If you can't use C++17, or the class doesn't have a copy/move c'tor, then yes, that might be the way to go. I try to avoid it though and try to put that logic into named functions. Also, while the check in the example code is simple, the comment says Complex checks which most likely means in the OP's real code, a simple check like that might not be enough. Hence, I show this approach.
2

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; } }; 

1 Comment

I learned something new today! I'll squirrel this nugget away as "I hope I never have code where I need to do this." But if I do, now I know how to do it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.