abo-abo
abo-abo

Reputation: 20342

C++ construct a series of interdependant classes with no default constructor?

I have classes A,B,C,D from a foreign library with no default constructors.

object A is given. object D is required.

I can't write

D makeD(A a) {
  B b(1,2,3);
  C c(a,b);
  c.setParam1(4);
  c.setParam2(5);
  return D(a,b,c);
}

because the destruction of the intermediates B and C makes the returned D object unusable (D stores B and C by reference).

what is the shortest solution to this problem?

One ugly and bad but short solution is this:

D makeD(A a) {
  B* b=new B(1,2,3);
  C* c=new C(a,*b);
  c->setParam1(4);
  c->setParam2(5);
  return D(a,*b,*c);
}

One long solution would be:

shared_ptr_xxl<D,B,C> makeD(A a) {
  B* b=new B(1,2,3);
  C* c=new C(a,*b);
  c->setParam1(4);
  c->setParam2(5);
  return shared_ptr_xxl<D,B,C>(new D(a,*b,*c),b,c);
}

where

shared_ptr_xxl<D,B,C> 

is like

shared_ptr<D> 

except it has additionaly has

delete b;
delete c; 

in the destructor.

Upvotes: 0

Views: 119

Answers (2)

David Stone
David Stone

Reputation: 28813

Create a class that contains them all:

class E {
    public:
        E(A const & a):
            b(1, 2, 3),
            c(make_c(a, b)),
            d(a, b, c)
            {
        }
    private:
        static C make_c(A const & a, B const & b) {
            C c(a, b);
            c.setParam1(4);
            c.setParam2(5);
            return c;
        }
        A a;
        B b;
        C c;
        D d;
};

Upvotes: 1

tp1
tp1

Reputation: 1207

One good solution is copying all the data:

void makeD(A a, D &d2) {
   B b(1,2,3);
   C c(a,b);
   c.setParam1(4);
   c.setParam2(5);
   D d(a,b,c);
   CopyFrom(d,d2);
}

But it obviously requires support from the foreign library... It helps if the foreign lib can publish all it's data structures via interface of the objects.

CopyFrom() will call member functions of d and copy the data to d2. In practise, it's often the case that d and d2 have different types..

Lets try this with std::vector:

void makeD(std::vector<int> &vec2) {
   std::vector<int*> vec;
   int a=10,b=20,c=30;
   vec.push_back(&a);
   vec.push_back(&b);
   vec.push_back(&c);
   CopyFrom(vec, vec2);
}

Then CopyFrom would look like:

void CopyFrom(std::vector<int*> vec, std::vector<int> &vec2) {
   for(int i=0;i<vec.size();i++) vec2.push_back(*vec[i]);
}

Upvotes: 0

Related Questions