4

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

Community
  • 1
  • 1
silentwf
  • 153
  • 2
  • 8

4 Answers4

2

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;
};
ArnonZ
  • 3,822
  • 4
  • 32
  • 42
  • Do you have code you can show for an example? Its hard for me to grasp your concept as I'm not too familiar with C++ – silentwf Aug 10 '14 at 19:06
  • Added the code for ya. I like the second solution best because of its OOP nature. it can also help (with little modifications) if you need the same DataConfiguration for many C0 instances (C0 can get it in the c'tor for instance). All depends on the inner logic of your code. – ArnonZ Aug 10 '14 at 21:09
  • Also, regarding the question you asked on pointers, using pointers is just a tiny bit slower than using stack objects (as used in the second solution). For example, if you create lots of C0 classes throughout the operation of your application then you'd probably prefer not to use pointers. – ArnonZ Aug 10 '14 at 21:19
2

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 ;
    }
};
P0W
  • 46,614
  • 9
  • 72
  • 119
  • It works great! Is there any advantages/disadvantages using this method over the pointer or shared pointers as others have suggested? – silentwf Aug 10 '14 at 19:03
  • @silentwf As in current state, I don't see a need for smart pointer here. However, it all depends on your design. If you have design specific question you can post a new question when you're _really_ lost. – P0W Aug 10 '14 at 19:26
1

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);.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

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;
};
José Tomás Tocino
  • 9,873
  • 5
  • 44
  • 78