silentwf
silentwf

Reputation: 153

C++ Class member is an object that requires a constructor... which requires a function to instantiate

The question I'm asking appeared many times but not specific enough for mine. In my case, I have a class (lets call C0) that has a member which is a class (call this C1) which requires a constructor. However, in my case, I want to do some processing before I pass the variable into the constructor of C1. Is there a way to do this? In essence I would like to achieve something like this: (which of course doesn't work)

class C0{
public:
  C0(){
    ComplexDataType data;
    //Do some process with data
    myC1(data);
   }
private:
  C1 myC1;
};

class C1{
public:
  C1(ComplexDataType data);
}

I've seen the initialization list from here but my only thought about how to do it would result in a VERY ugly initialization list, something like this: (which works)

class C0{
public:
  C0() : variable1(doSomething1), variable2(doAnotherThing), variable3(keepItWorking), data(finallyDoSomethingWithTheOtherVariables), c1(data)
{
  //Something
};

class C1{
//Stuff
};

Is there an elegant way to achieve what I desire?

Update Oh yes, I forgot to mention: I cannot change anything in class C1

Upvotes: 4

Views: 117

Answers (4)

Zilicon
Zilicon

Reputation: 3860

I see a couple of ways to resolve this

You can hold a pointer to myC1 in C0. then inside C0's c'tor you can process your data and then set myC1 = new myC1(data);

class C0 {
public:
  C0() {
    ComplexDataType data;
    //Do some process with data
    myC1 = new C1(data);
  }
private:
  C1 *myC1;
};

Or, if it makes sense you can add a new class that will do the preliminary work in its c'tor and declare it (and thus create it) before myC1 in C0, then pass its result (using a get method) to myC1 upon creation.

class DataConfiguration {
public:
  DataConfiguration() {
    //Do some process with data 
  }
  const ComplexDataType &getData() {
    return data;
  }
private:
  ComplexDataType data;
};

class C0 {
public:
  C0() :
      dataConf(),
      myC1(dataConf.getData()) {
  }
private:
  DataConfiguration dataConf;
  C1 myC1;
};

Upvotes: 2

P0W
P0W

Reputation: 47784

If I understood correctly, looks like you want to do some processing, then initialize your class member using initialization list.

You can use a static member to achieve this like following :

class C0{
public:
  C0():  myC1(process()){

    //Do some process with data

   }
private:
  C1 myC1;

    static ComplexDataType process()
    {
        ComplexDataType data;
        // ... do stuff
        return data ;
    }
};

Upvotes: 2

I'm guessing you cannot modify the C1 class, so you should seriously consider using pointers. You could even use a shared_ptr to forget about freeing the memory once you don't need the object anymore.

class C0{
public:
  C0(){
    ComplexDataType data;
    //Do some process with data
    myC1 = std::make_shared<C1>(data);
   }
private:
  std::shared_ptr<C1> myC1;
};

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409136

You could implement an copy-assignment operator for C1 (which you probably should to anyway) and in the C0 constructor just do e.g. myC1 = C1(data);.

Upvotes: 1

Related Questions