Инициализация аггрегируемого объекта
От: Аноним  
Дата: 23.09.04 04:24
Оценка:
Добрый день!

Пусть есть код:
class A
{
public:
  A();
  ~A();

  void SetId( int _id) { id = _id; };

private:
  int id;
};

class B
{
public:
  B();
  ~B();

  A a1, a2, ... , aN;

};

Теперь при создании экземпляров класса B необходимо проинициализировать аггрегируемые им объекты a1, a2, ... , aN.
Сейчас просто напрямую обращаюсь к этим объектам т.к. они public
B b1, b2;
b1.a1.SetId(1);
b1.a2.SetId(8);
//............
b1.aN.SetId(5);

b2.a1.SetId(11);
b2.a2.SetId(4);
//............
b2.aN.SetId(9);

Но такой подход как-то не вписывается в концепцию инкапсуляции и по-хорошему объекты a1, a2, ... , aN надо выносить в private область. Тем более что дальше они используются только в контексте класса B.
Вопрос: как это сделать красиво и эффективно?

Первое что приходит в голову это передавать структуру с данными инициализации
typedef struct
{
  int a1, a2, ... , aN;
} INIT_PARAM;

class B
{
public:
  B();
  ~B();

  void InitA( INIT_PARAM *pPar)
  {
    a1.SetId( pPar->a1);
    // ...........
  };
private:
  A a1, a2, ... , aN;
};

ну и соот-но использовать
INIT_PARAM par;
B b1, b2;
par.a1 = 1;
// ......
b1.InitA(par);

par.a1 = 11;
// ......
b2.InitA(par);

Но в этом случае мы получаем дополнительное расбухание кода и накладные расходы по инициализации.

Наверняка проблема уже сто раз поднималась и хотелось бы знать как ее решаете Вы?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.