Существует ли симметричный шаблон проектирования, чтобы классы-члены могли иметь указатели друг на друга? - PullRequest
1 голос
/ 29 февраля 2012

У меня вопрос о дизайне.У меня есть класс, скажем, класс S, который имеет два класса-члена, P и C. Класс P должен вызывать функции-члены из класса C, а класс P должен вызывать функции-члены из C.

Прямо сейчасЯ имел дело с тем, чтобы сначала создать C и передать его P, а затем сделать P статическим, чтобы к его функциям-членам можно было обращаться из C. (Возможно, что позже у меня будет массив классов C, но я будувсегда есть одна буква P - вот почему я могу сделать ее статичной)

Мой вопрос: есть ли лучший способ настроить это?Мне не нравится делать P статическим - в идеале, я бы хотел, чтобы C и P имели указатели друг на друга, но как?

Приложен какой-то слишком упрощенный код.

Спасибо!

#include <iostream>

class C;

class P {
   C *c;
   P (C *x ): c(x)  {};

 public:
    static P *p;
    static P *get_P(C *x) { if (!p) { p= new P(x);}; return p;};
    static P *get_P () { return p;}

    void P_function ();
    void P_other ();
};

class C {
  public:
    C ()  {};
    void C_function ()
    {
      std::cout << "in C_funtion\n";
    }
    void C_other ()
    {
      P::get_P()->P_function();
    }
};

void P::P_other ()
{
  c->C_function();
}

void P::P_function ()
{
  std::cout << "in P_funtion\n";
}

class S {
  public:
  C c;

  S()
  {
     P::get_P(&c);
  };
};

P* P::p = NULL;

int main ()
{
  S s;

  s.c.C_other();
  P::get_P()->P_other();

}

1 Ответ

2 голосов
/ 29 февраля 2012

В ваших заголовочных файлах не включайте другой класс, только предварительное объявление и используйте указатели:

// C.h
#ifndef C_H
#define C_H
class P;

class C 
{
     P *p;
public: 
     C (P *x ); 
     // *** no inline implementation of methods calling P methods here!!
}
#endif

То же самое относится к P, но не передайте объект C через конструктор, передайте его отдельным методом в объект P (чтобы избежать очевидной проблемы курицы или яйца при конструировании двух объектов).

// P.h
#ifndef P_H
#define P_H
class C;

class P 
{
     C *c;
public: 
     P (); 
     void SetC(C *x){c=x;}
}
#endif

В ваших файлах CPP включите C.h в P.cpp и P.h в C.cpp, затем вы можете вызывать методы P в C и наоборот.

Теперь в вашем классе S сначала создайте объект P, затем создайте объект C, передав ему объект P, и, наконец, передайте объект C в P с помощью SetC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...