Russian Qt Forum
Апрель 18, 2024, 10:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Шаблоны, наследование и методы  (Прочитано 3420 раз)
System
Гость
« : Март 30, 2015, 10:19 »

Имеется следующий код:
Код
C++ (Qt)
#include <cstdio>
 
template<int N> class Tmpl {
   private :
       void _f() {
           printf("Template. %d\n", N);
       }
   public :
       void f() {
           _f();
           printf("%d\n", N);
       }
};
 
class Instance : public Tmpl<1> {
   private :
       void _f() {
           printf("Instance.\n");
       }
};
 
int main() {
   Instance* instance = new Instance();
   instance->f();
   delete instance;
   return 0;
}
 
Результат выполнения:
Код
DOS
Template. 1
1
Необходимо изменить этот код так, чтобы вместо Tmpl::_f вызывалась Instance::_f.

Первое решение - объявить _f виртуальной. Однако, это решение использовать в данном случае нельзя. Как ещё можно добиться требуемого результата?
Записан
System
Гость
« Ответ #1 : Март 30, 2015, 11:33 »

Нашёл один вариант:
Код
C++ (Qt)
#include <cstdio>
#include <cassert>
 
template<int N, class Derived> class Tmpl {
   private :
       void _f() {
           printf("Template. %d\n", N);
       }
   public :
       void f() {
           static_cast<Derived*>(this)->_f();
           printf("%d\n", N);
       }
};
 
class Instance : public Tmpl<1, Instance> {
   friend class Tmpl<1, Instance>;
   public :
       void _f() {
           printf("Instance.\n");
       }
};
 
int main() {
   Instance* instance = new Instance();
   instance->f();
   delete instance;
 
return 0;
}
 
Может, есть другие решения? Какое-то оно... Через одно место, как мне кажется...
« Последнее редактирование: Март 30, 2015, 11:36 от System » Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #2 : Март 30, 2015, 14:42 »

http://rextester.com/QGDYN30725

Код:
#include <cstdio>
 
template<class T, int N> struct Tmpl
{
    void f()
    {
        static_cast<T*>(this)->_f();
        printf("%d\n", N); 
    }
};
 
struct Instance : Tmpl<Instance, 1>
{
    void _f() { printf("Instance.\n"); }
};
 
int main() {
    Instance* instance = new Instance();
    instance->f();
    delete instance;
    return 0;
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Март 31, 2015, 09:01 »

С интересом наблюдал за темой, тоже нашел это решение, но подумал что private обходить нельзя, поэтому не годится. Скажите, а есть еще какие-то пути или только этот единственный?

Спасибо
Записан
System
Гость
« Ответ #4 : Март 31, 2015, 09:51 »

К сожалению, private обходить действительно нельзя. Функция _f() должна быть скрытой от кода, использующего класс. Максимум - объявить protected.  Подмигивающий Решение со static_cast и friend мне не очень нравится, но, похоже, придётся реализовывать именно его в связи с отсутствием других предложений.
Записан
System
Гость
« Ответ #5 : Март 31, 2015, 10:12 »

Можно чуть упростить код, написав
Код
C++ (Qt)
friend class Tmpl;
вместо
Код
C++ (Qt)
friend class Tmpl<1, Instance>;
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.117 секунд. Запросов: 23.