views:

142

answers:

4
+2  Q: 

C++ shared objects

Hello,

I have got four classes A, B, C and D.

  • Class A has a member b of class B.
  • Class B has a member c of class C.

A has a member D* dpointer;

This hierarchy has to be preserved (in fact this is a GUI with app, window, panel as A, B and C).

Now B and C must use a method from *dpointer.

Is there something more elegant than giving dpointer as a member of B and C ? Is it bad ?

+2  A: 

Not directly, but you could put D inside of a shared_ptr<D>, which would alleviate any memory management headaches you might possibly have.

Billy ONeal
+1  A: 
struct D;
struct CommonABC
{
   CommonABC(D * & dpointer) : dpointer(dpointer) {}
   D * & dpointer;
};
struct C : CommonABC 
{
   C (const CommonABC & common) : CommonABC(сommon) {}
};
struct B: CommonABC 
{
   B (const CommonABC & common) : CommonABC(сommon), c(common) {}
   C c;
};
struct A 
{
   A () : b(CommonABC(dpointer)) {}
   D * dpointer;
   B b;
};
Alexey Malistov
Why the references to pointers? Why not just store the pointer directly?
Billy ONeal
Because you can change `dpointer` in `struct A` and get changed value in `B` and `C`.
Alexey Malistov
+1  A: 

In this situation you should probably pass a reference to B and C instead of a pointer. As @Billy ONeil says in his answer, you should use a shared_ptr or a scoped_ptr if possible and appropriate (cannot judge without knowing more about D and dpointer) in A. Passing a reference to B and C has the advantage of making clear that these two merely use the D-object, but do not control it's lifecycle, and that an instance of D is required to use these classes (with a pointer NULL would be an option). If B and C only call const methods on D, you can even pass a const reference.

Space_C0wb0y
+1  A: 

In practice, I would probably opt for the shared_ptr solution mentioned above. But here is another way that is not often covered in the C++ literature, of the sort you might find in an interview question or a BrainBench test:

struct D{
  D(int val);
  void foo();
};
struct C:private virtual D{
  void bar(){
    foo();
  } 
};
struct B:private C,private virtual D{
  void car(){
    foo();
  }
};

struct A:private B,private virtual D{   
   A(int val):D(val){}
   void aar(){
    car();
    foo();
   }

};

private inheritance implements the has-a relationship, just like making it a member. The only difference is that you can only have one of each type. In this case the same D object is shared by all classes in the composition.

But if you want others to be able to understand what you are doing, go with the shared_ptrs.

Lance Diduck