C ++ разделяемые объекты - PullRequest
       37

C ++ разделяемые объекты

2 голосов
/ 26 апреля 2010

У меня есть четыре класса A, B, C и D.

  • Класс A имеет члена b класса B.
  • Класс B имеет члена c класса C.

A имеет члена D* dpointer;

Эта иерархия должна быть сохранена (фактически это графический интерфейс с приложением, окном, панелью в виде A, B и C).

Теперь B и C должны использовать метод из *dpointer.

Есть ли что-то более элегантное, чем дать dpointer в качестве члена B и C? Это плохо?

Ответы [ 4 ]

2 голосов
/ 26 апреля 2010

Не напрямую, но вы можете поместить D в shared_ptr<D>, что уменьшит любые возможные проблемы с управлением памятью.

1 голос
/ 26 апреля 2010

На практике я, вероятно, выбрал бы решение shared_ptr, упомянутое выше. Но вот еще один способ, который не часто рассматривается в литературе по C ++, такой, какой вы можете найти в вопросе об интервью или тесте BrainBench:

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();
   }

};

частное наследование реализует отношение has-a, подобно тому, как делает его членом. Разница лишь в том, что вы можете иметь только один из каждого типа. В этом случае один и тот же объект D является общим для всех классов композиции.

Но если вы хотите, чтобы другие могли понять, что вы делаете, перейдите к shared_ptrs.

1 голос
/ 26 апреля 2010

В этой ситуации вы, вероятно, должны передать ссылку на B и C вместо указателя. Как говорит @Billy ONeil в своем ответе , вы должны использовать shared_ptr или scoped_ptr, если это возможно и целесообразно (не можете судить, не зная больше о D и dpointer) в A. Передача ссылки на B и C имеет то преимущество, что дает понять, что эти два типа просто используют D -объект, но не управляет его жизненным циклом, и что для использования этих классов требуется экземпляр D (с указателем NULL будет вариант). Если B и C вызывают только const методы для D, вы даже можете передать константную ссылку.

1 голос
/ 26 апреля 2010
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;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...