Re[2]: Зачем нужен невиртуальный деструктор?
От: bzzz  
Дата: 10.02.11 15:24
Оценка:
Здравствуйте, rg45, Вы писали:

R>
R>class IFoo
R>{
R>public:

R>  virtual void bar() = 0;
R>  virtual void baz() = 0;

R>protected:
R>  IFoo() { }
R>};
R>

R>Причем деструктор этого абстрактного класса я намеренно объявляю невиртуальным и защищенным, тем самым как бы подчеркивая, что стратегия владения объектами выбирается разработчиком производных классов. При этом у разработчика производного класса есть две возможности: 1) (традиционный) сделать деструктор производного класса открытым и виртуальным; 2) сделать деструктор невиртуальным и защищенным, а для создания объектов реализовать фабричный метод.

R>Пример второго варианта:

R>
R>using boost::shared_ptr;

R>class FooDerived1 : public IFoo
R>{
R>public:

R>  virtual void bar();
R>  virtual void baz();

R>  static shared_ptr<FooDerived1> create_instance(/*possible arguments*/);
R>  {
R>    return shared_ptr<FooDerived1>(new FooDerived(/*possible arguments*/));
R>  }

R>protected:
R>  FooDerived1();
R>};

R>class FooDerived2 : public IFoo { /*...*/ };
R>class FooDerived3 : public IFoo { /*...*/ };
R>

R>А вот теперь замечательный момент: умный указатель производного типа, возвращаемый фабричным методом create_instance, легко преобразуется в умный указатель абстрактного типа. Это позволяет владеть объектами и корректно удалять их полиморфно:
R>
R>int main()
R>{
R>  typedef std::vector<boost::shared_ptr<IFoo> > Items;

R>  Items items;
R>  items.push_back(FooDerived1::create_instance(/*possible arguments*/));
R>  items.push_back(FooDerived2::create_instance(/*possible arguments*/));
R>  items.push_back(FooDerived3::create_instance(/*possible arguments*/));

R>  //...
R>}
R>


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