вассал моего вассала - не мой вассал (friend и наследование)
От: programmater  
Дата: 06.05.06 17:54
Оценка:
Уважаемый All.
Есть задача — локализовать создание объектов. Т.е. есть объект-контейнер и есть итемы этого контейнера. Есть иерархия контейнеров, есть иерархия итемов. Задача в том, что итем не может существовать в пустоте — он обязан принадлежать контейнеру. Поэтому хочется сделать конструктор итема закрытым и разрешать создавать итемы только потомкам базового контейнера. Первое, что приходит в голову — объявить конструктор итема протектным и объявить BaseContainer friend-ом итема. Типа такого:

class Item
{
  friend class BaseContainer;
  protected:
   Item() {/*создание*/};
   virtual ~Item() {};
  public:
  // что-то
};
class DerivedItem1: public Item
{
  friend class BaseContainer;
  protected:
   DerivedItemItem1() {/*создание*/};
   virtual ~DerivedItem1() {};
  public:
  // что-то
};
class BaseContainer
{
  public:
    Item* CreateItem() 
    {
      Item* RetItem = new Item();
      // Воткнуть RetItem в контейнер
      return RetItem;
    }
    void DestroyItem(Item* it) {/* вытащить it из контейнера*/ delete it;}
};
// До этого момента все хорошо. Но вот появился DerivedContainer, поддерживающий DerivedItem1
// BaseContainer править не хочется. Пытаюсь писать
class DerivedContainer : public BaseContainer
{
  public:
    Item* CreateItemInDerivedContainer()
    {
      Item* RetItem = new Item();
      // Воткнуть в контейнер, но по-другому, чем в BaseContainer
      return RetItem;
    }
    DerivedItem1* CreateDerivedItem()
    {
      DerivedItem1* RetItem = new DerivedItem1();
      // Воткнуть в контейнер
      return RetItem;
    }
};


Все бы хорошо, но friend-ность не наследуется. Т.е. в наследнике BaseContainer-а я не могу создавать итемы!!! И при попытке вызвать new Item() в DerivedContainer я тут же получаю по глове от компилятора типа "не могу вызвать протектед функцию (си декларейшин оф Item::Item)". То, что DerivedContainer является наследником BaseContainer никого не волнует. Вот облом. Как обойти это ограничение или какие есть другие решения данной задачи (надеюсь задача ясна).
Спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.