0

I would like to be able to initialize a class member in one of N ways (in this examples N=2) based on a condition that is recieved via the class constructor as in the code that follows, but the MainObject's initialization seems to be only local to the (container) class' constructor. I wonder what are the best-practices for this particular pattern.

// in ContainerObject.hpp

class ContainerObject {
public:
    MainClass MainObject;
    ContainerObject(int type);
}



// in ContainerObject.cpp

ContainerObject::ContainerObject(int type);{
    if (type == 0){
        MainObject("something", 1, 2);
    } else if (type == 1){
        MainObject(4, "another thing", "yet another thing");
    }
}

I have so-far thought about

  1. putting the main object in the heap
  2. defining N class constructors and call the appropiate one recursively inside the "main"/"first" class constructor.

please note that the "0" and "1" initialization is only an example and it could be drastically different.

EDIT1: added ";" required for compiling EDIT2: Changed the original

//...
if (type == 0){
    MainObject(0);
} else if (type == 1){
    MainObject(1);
}
//...

for the current one

//...
if (type == 0){
    MainObject("something", 1, 2);
} else if (type == 1){
    MainObject(4, "another thing", "yet another thing");
}
//...

as it was called a duplicate by being misinterpreted for a case that could be solved by adding the following.

//...
ContainerObject(int type): MainObject(type);
//...
3
  • Duplicate? stackoverflow.com/questions/1711990/… Commented Oct 29, 2021 at 14:48
  • Beides that, you have an excess ; after the signature in the constructor definition. Commented Oct 29, 2021 at 14:50
  • Indeed the question mentions "N" possible types, so it's a matter of extending the conditional clause to include type == 2, ..., type == N-1 and adding some realistic error handling if type exceeds "N". Commented Oct 29, 2021 at 15:05

2 Answers 2

2

I am interpreting the question as "how to perform non-trivial logic before/during the member initialization list".

A good way to go about that is to delegate the work of converting the constructor parameter of the outer object into the child object to a utility function:

// in ContainerObject.cpp

#include <stdexcept> // for std::invalid_argument

// Anonymous namespace since main_factory() is only needed in this TU.
namespace {

MainClass main_factory(int type) {
  if (type == 0) {
    return MainClass("something", 1, 2);
  } else if (type == 1) {
    return MainClass(4, "another thing", "yet another thing");
  }

  // N.B. This is one of the scenarios where exceptions are indisputably
  // the best way to do error handling.
  throw std::invalid_argument("invalid type for MainClass");
}

}

ContainerObject::ContainerObject(int type) 
  : MainObject(main_factory(type)) {}

Sign up to request clarification or add additional context in comments.

6 Comments

Please note the question states please note that the "0" and "1" initialization is only an example and it could be drastically different.. In particular it could require different amount and type of objects depending on each type.
@Gaston: that why there is foo and not directly MainObject(type). foo might even return a MainClass.
Could you please show a function that provides MainObject's constructor with two possible inputs as required now, after EDIT2?
@Gaston I updated the answer to match the updated question.
Is there a workaround to MainClass not being copyable because of its constructor being private?
|
1

A constructor is always called automatically whenever an object is created. You can never call it by yourself anywhere.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.