inheritance - Limit object sharing of virtual base classes in C++ -


i know physical , virtual inheritance in c++. however, know if model somehow achieved design patterns or tricks.

the classes e , f , bases of should not modified.. imagine come extern library.

everything below e , f open. ok introduce intermediate helping classes, non-member function, templates... realize this:

           baseclass            /       \           /         \                            / \         / \        /   \       /   \       b     c     b     d        \   /       \   /         \ /         \ /          e           f           \         /            \       /             \     /            finalclass 

note e , f shall not share a. finalclass should indeed contain 2 a. problem is, creation of e or f require, b, c , d inherit virtually.. however, if virtual base class, compiler create 1 object in finalclass instead of 2 different ones.

so, think many of recommend composition instead of inheritance here. however, composition modells "has a"-relationship here , not "is a"-relationship. in explaination, finalclass behave e or f, including being able convert classes.

this layout not feasible in c++, additional helping class.

the fact that b inherits a, , want share inheritance c on 1 side , d on other, requires b, c , d virtually inherit a. shared accross both branches of diamond.

alternatives

what alternatives there ?

  • if you'd manage break sharing of between left , right branches of diamonds, break sharing of common base.

  • if you'd introduce intermediary classes a1, a2 implementing left , right share in branches, you'd stuck fact both b have inherit either 1 or other

  • the way out have duplicate class b.

this last solution doesn't fulfill requirement follows:

struct base { int x; }; struct : public virtual base { int a; }; struct ac : public a{};  // synonym  struct b : public virtual { int b; }; struct bc : public virtual ac { int b;  }; // !! clone !!  struct c : public virtual ac { int c; }; struct d : public virtual { int d; }; struct e : public bc, c { int e; }; struct f : public b, d { int f; }; struct final : public e, f { }; 

and here access memebers:

final f; f.x = 2;    // unambiguous:  there's onely 1 of  f.f = 1;  f.e = 2;  f.d = 3;  f.c = 4;  //f.b = 5;   // ambiguous:  there 2 of  f.e::b = 5;  // successful desambiguation f.f::b = 6;  // successfuldesambiguation //f.a = 7;   // ambiguous:  there 2 of f.e::a = 7;  // successful desambiguation f.f::a = 8;  // successful desambiguation 

to come problem statement: can't intervene above e , f. in case options limited :

  • you publicly inherit
  • you privately inherit via intermediary classes

but effect same on sharing, following code desmonstrates (on top of above one) :

class fi : private f  // make f private { public:      void set_xa(int u, int v) { x = u; a= v; }     void show_xa() { cout << "x:" << x << " a:" << << endl; } }; class ei : private e  // make e private { public:     void set_xa(int u, int v) { x = u; = v; }     void show_xa() { cout << "x:" << x << " a:" << << endl; } };  struct final3 : public ei, public fi { };   final3 h; h.ei::set_xa(3, 4); h.fi::set_xa(5, 6); h.ei::show_xa();  h.fi::show_xa(); // shared virtually inherited memebers still shared ! 

conclusion:

with inheritance, you're bound design above e , f aren't allowed influence.

so first questions be:

  • can't alter design after (i.e. cloning of 1 b) ?
  • wouldn't unacceptable of having shered between both branches (may there's valid reason after all) ?

if answer no both questions, you'll have go composition, , implement kind of proxy design pattern, composed object proxy both components.


Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -