Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наследование через templates, зачем  
:(
    Опции темы
sergioK1
Дата 22.11.2013, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Плюс понятнен это быстрее через vTable , в чем минусы  ?

Код


emplate <typename Derived>
struct Parent {
  private: Derived* value;

    public :
   //  Parent (Derived x):value(x){
    //};
    void doIt(){
        Derived* derived = (static_cast<Derived *>(this));
        derived->print();
      //std::cout << (static_cast<const T *>(this))->value << " parent\n";
    }
   void print(){
      std::cout << "parent "<<std::endl;
      Derived* derived = (static_cast<Derived *>(this));
      derived->print();
  }
};

class Derived  : public Parent<Derived>{

  public:
   Derived(): value(10){
     std::cout << " ctor "<<std::endl;
   }
   void print(){
      std::cout << " derived "<<value <<std::endl;
  }

  private :
   int value;
};



PM MAIL   Вверх
ZeusAtVingrad
Дата 22.11.2013, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.4.2006

Репутация: нет
Всего: нет



Подозреваю: минусы - в отсутствии полиморфизма?
PM MAIL   Вверх
vinter
Дата 22.11.2013, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Подобные подходы используют по разным причинам. Вот у тебя один из примеров, как это можно использовать. Правда, на мой взгляд, так никто не делает в силу того, что подход будет ничем не быстрее vtable, а может быть и медленнее.

Из головы примеры придумать сложно(как правило такие подходы используют в конкретных контекстах), лучше рассматривать конкретные примеры. Так же в каждом случае будут свои плюсы и минусы.



--------------------
Мой блог
PM MAIL WWW   Вверх
sergioK1
Дата 24.11.2013, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(vinter @ 22.11.2013,  08:56)
Подобные подходы используют по разным причинам. Вот у тебя один из примеров, как это можно использовать. Правда, на мой взгляд, так никто не делает в силу того, что подход будет ничем не быстрее vtable, а может быть и медленнее.

Из головы примеры придумать сложно(как правило такие подходы используют в конкретных контекстах), лучше рассматривать конкретные примеры. Так же в каждом случае будут свои плюсы и минусы.

Нет поиска в таблице виртуальных функций , а это чуть медленнее, 
Хотя наследование это  лишь частный случай 

Код

 template <typename Any>
class Base{

    public:
    Base(Any& t):t(t){
      }

      void foo(){
        t.print();
        std::cout<<" base "<<std::endl;
        t.foo();
      }

     private:
       //  T& child;
       Any& t;
};


т,е, Я принимаю интерфэйс , ZeusAtVingrad  полиморфизм чистой воды только на стадии компиляции, 
проблема в том что конструктор класса Any может быть еще не вызван ,
 т,е, если метод скажем делает скажем value++ , где value - private member , то он не проинициализирован , как мне закрыть эту дыра 
  
PM MAIL   Вверх
ZeusAtVingrad
Дата 24.11.2013, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.4.2006

Репутация: нет
Всего: нет



Что-то мало что понял.
Просто у меня отложилось, что в C++ полиморфизм это - виртуальные функции.
Ну и логично предположить, что если нет виртуальных функций, то и полиморфизма нет.
PM MAIL   Вверх
vinter
Дата 25.11.2013, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата

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

Какого поиска? там всё на индексах. 
Цитата(ZeusAtVingrad @  25.11.2013,  00:26 Найти цитируемый пост)
Просто у меня отложилось, что в C++ полиморфизм это - виртуальные функции.

у тебя правильно отложилось, правда шаблоны иногда называют "статическим" полиморфизмом, но это не совсем то о чем обычно говорят при обсуждении полиморфизма.


--------------------
Мой блог
PM MAIL WWW   Вверх
sergioK1
Дата 25.11.2013, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(vinter @ 25.11.2013,  06:33)
Цитата

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

Какого поиска? там всё на индексах. 
Цитата(ZeusAtVingrad @  25.11.2013,  00:26 Найти цитируемый пост)
Просто у меня отложилось, что в C++ полиморфизм это - виртуальные функции.

у тебя правильно отложилось, правда шаблоны иногда называют "статическим" полиморфизмом, но это не совсем то о чем обычно говорят при обсуждении полиморфизма.

Вот Я тоже подозреваю , а поподробней про индексы есть ссылки ?? 
PM MAIL   Вверх
vinter
Дата 25.11.2013, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



поищи любым поисковиком на предмет реализации таблицы виртуальных функций в интересующем тебя компиляторе. У меня под рукой ссылок нет.


--------------------
Мой блог
PM MAIL WWW   Вверх
Lukkoye
Дата 20.12.2013, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: 1
Всего: 1



Цитата(sergioK1 @  22.11.2013,  00:05 Найти цитируемый пост)
Плюс понятнен это быстрее через vTable , в чем минусы  ?


Что такое "запуск через vtbl" ?

Это - запуск функции, адрес которой находится по указателю. Если сказать совсем просто: "запуск функции не напрямую, а через указатель".

Теперь внимательно смотрим на ваш пример:

Код

void doIt(){
        Derived* derived = (static_cast<Derived *>(this));
        derived->print();
      //std::cout << (static_cast<const T *>(this))->value << " parent\n";
    }


Что мы видим? Мы видим получение указателя, и запуск через этот указатель.
Вам это ничего не напоминает?

Итого: данный способ не имеет профита к скорости работы по сравнению с vtbl, поскольку использует тот же самый принцип действия.

Кто-то может сказать: умный компилятор может оптимизировать второй вариант, поскольку во втором варианте на этапе компиляции можно вычислить значения всех адресов. И это действительно так. Правда в том, что такой умный компилятор сможет соптимизировать и виртуальную функцию тоже.

Минус данного подхода в том, что это ничто иное, как велосипед, который вручную имитирует работу виртуального полиморфизма.

Минус здесь - код становится сложнее. Возможные ошибки на совести программиста, а не компилятора.
Базовый класс - шаблонный, поэтому его целиком придется держать в хэдере.

И тп.


Резюмируя: нет ни одной причины делать в ручную то, что за вас может сделать умная автоматика. В ручную нужно делать лишь то, что автоматика сделать не может.


Для шаблонных базовых классов, есть своя область применения. Например:

Код

//вот так любой класс легко можно сделать сингелтоном
class Some: public Singelton<System> 

   ...
}; 


//вот так для любого класса можно запретить конструктор копирования
class Some: public NoCopyable<System> 

   ...
}; 



Если же вам по задаче понадобилось использовать полиморфизм - используйте полиморфизм. Предоставьте дело автоматике.

Сделать косвенную адресацию эффективнее, чем это может сделать компилятор у вас все равно не получится.


PM MAIL   Вверх
baldina
Дата 21.12.2013, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(ZeusAtVingrad @  24.11.2013,  23:26 Найти цитируемый пост)
Просто у меня отложилось, что в C++ полиморфизм это - виртуальные функции

в С++ два вида полиморфизма - динамический (виртуальные функции) и статический (шаблоны).
отсюда сразу ясно в чем минусы виртуальности через шаблоны - это не подходит в случаях, когда тип неизвестен во время компиляции.
то, о чем идет речь, называется CRTP, и его применение не ограничиваются приведенным примером. впрочем, все они статические smile
PM MAIL   Вверх
sergioK1
Дата 22.12.2013, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(baldina @ 21.12.2013,  17:28)
Цитата(ZeusAtVingrad @  24.11.2013,  23:26 Найти цитируемый пост)
Просто у меня отложилось, что в C++ полиморфизм это - виртуальные функции

в С++ два вида полиморфизма - динамический (виртуальные функции) и статический (шаблоны).
отсюда сразу ясно в чем минусы виртуальности через шаблоны - это не подходит в случаях, когда тип неизвестен во время компиляции.
то, о чем идет речь, называется CRTP, и его применение не ограничиваются приведенным примером. впрочем, все они статические smile

когда неизвестен на этапе компиляции делаеться фабрика , 
ее, как вариант,  можно сделать внутри template ,

Когда еще вы применяли CRTP ?, меня именно это и интересует 
PM MAIL   Вверх
baldina
Дата 23.12.2013, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(sergioK1 @  22.12.2013,  20:24 Найти цитируемый пост)
когда неизвестен на этапе компиляции делаеться фабрика
это для создания объекта. а при создании объекта (динамический) полиморфизм непричем.

кстати фабрика тоже может быть статической или динамической.

CRTP применяется для более четкого разделения интерфейса и реализации: это mixins и статический полиморфизм. Пользоваться тем, что базовый класс знает точный типа объекта, можно не только для статического полиморфизма, но и например для реализации клонирования, вроде
Код

Base *clone() {
  return new Derived(static_cast<Derived>(*this));
}


PM MAIL   Вверх
sergioK1
Дата 23.12.2013, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



Цитата(baldina @ 23.12.2013,  09:30)
Цитата(sergioK1 @  22.12.2013,  20:24 Найти цитируемый пост)
когда неизвестен на этапе компиляции делаеться фабрика
это для создания объекта. а при создании объекта (динамический) полиморфизм непричем.

кстати фабрика тоже может быть статической или динамической.

CRTP применяется для более четкого разделения интерфейса и реализации: это mixins и статический полиморфизм. Пользоваться тем, что базовый класс знает точный типа объекта, можно не только для статического полиморфизма, но и например для реализации клонирования, вроде
Код

Base *clone() {
  return new Derived(static_cast<Derived>(*this));
}

Мне всегда казалось что наследование лучше там где точно знаешь что интерфейс базового
класса не будет меняться,  
про  "более четкое разделения интерфейса и реализации" не допонял , что 
 не четко 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0899 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.