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

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

Страниц: [1] 2 3 ... 6   Вниз
  Печать  
Автор Тема: Шаблоны.  (Прочитано 36741 раз)
Андрей
Гость
« : Март 24, 2012, 11:41 »

Могу ли я наследовать класс от шаблона следующим образом?
Код
C++ (Qt)
template <class Ti, class Tp>
class VVectorIndex: public QObject
{  
public:
   VVectorIndex(QObject* parent = 0);
 
   virtual ~VVectorIndex();
   Ti getIndex(Tp*);
   Tp* getPointer(Ti);
   Ti createIndex(Tp* word);
   bool eraseIndex(Ti);
   Ti count(){return Indexes.count();};
   virtual unsigned char getWordVersion(Ti)=0;
   virtual bool incrWordVersion(Ti)=0;
   virtual char getGroupVersion()=0;
   virtual bool incrGroupVersion()=0;
 protected:
   QVector <Tp*> Indexes;
 private:
   virtual bool setWordVersion(Tp*word, unsigned char vers){return false;};
 
   char groupVersion;
   Ti badIndexes;
};
 
class VWord;
 
class VWordIndex: public VVectorIndex<unsigned short, VWord>
{
public:
   VWordIndex(QObject* parent = 0):VVectorIndex<unsigned short, VWord>(parent){};
   ~VWordIndex();
   unsigned char getWordVersion(unsigned short);
   bool incrWordVersion(unsigned short);
   char getGroupVersion();
   bool incrGroupVersion();
 
 private:
   bool setWordVersion(VWord *word, unsigned char vers);
};
 
« Последнее редактирование: Март 26, 2012, 09:53 от Пантер » Записан
mutineer
Гость
« Ответ #1 : Март 24, 2012, 12:11 »

Ну вроде все в порядке, можешь наследоваться. Только не уверен нормально ли будет форвард-декларэйшн VWord. А из-за чего вопрос? компил ругается?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Март 24, 2012, 12:27 »

"Пользуйтесь тегом для оформления кода" (а то читать неудобно)
Indexes = Indices (а лучше просто везде Index)

По существу: унаследоваться можете, и getWordVersion, incrWordVersion будут работать, но "задействовать их в виртуальных целях" не получится
Записан
Андрей
Гость
« Ответ #3 : Март 24, 2012, 14:01 »

Ругается...

Решил шаблоны освоить. Написал шаблон. Шаблон типонезависимый и не знает полей классов Ti и Tp. Описал частично его методы, понял что кое-где гораздо удобней, когда класс знает типы классов Ti и Tp.
 
Решил что нужно от него наследовать класс и в классе переопределять некоторые методы в зависимости от типов.

Вынес шаблон в отдельные cpp/h. Планирую описать там два шаблона VVectorIndex и VListIndex.

При компиляции выдаёт
Код:
ошибка: undefined reference to `VVectorIndex<unsigned short, VWord>::createIndex(VWord*)'
И так на каждую задействованную в коде функцию-метод шаблона, в том числе на
Код:
VWordIndex(QObject* parent = 0):VVectorIndex<unsigned short, VWord>(parent){};
выдаёт
Код:
ошибка: undefined reference to `VVectorIndex<unsigned short, VWord>::VVectorIndex(QObject*)'
« Последнее редактирование: Март 24, 2012, 14:03 от Андрей » Записан
Андрей
Гость
« Ответ #4 : Март 24, 2012, 14:08 »

Т.е. вообще нельзя "задействовать методы в виртуальных целях" наследуя от шаблона. А деструктор?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Март 24, 2012, 14:15 »

Т.е. вообще нельзя "задействовать методы в виртуальных целях" наследуя от шаблона. А деструктор?

Да можно, нормально там всё) 
А ошибки у вас выскакивают из-за того, что объявление и реализация шаблонных классов/функций должны нах. в одной единице трансляции. Перенесите из cpp всё обратно в h и всё заработает)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Март 24, 2012, 14:21 »

Да можно, нормально там всё) 
Интересно как. Прошу показать как задействовать напр метод getWordVersion (принимающий template аргумент) в виртуальном механизме
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #7 : Март 24, 2012, 14:33 »

Да можно, нормально там всё) 
Интересно как. Прошу показать как задействовать напр метод getWordVersion (принимающий template аргумент) в виртуальном механизме

Да легко:
Код
C++ (Qt)
template <class T>
class base
{
public:
   base() {}
   virtual ~base() {}
 
   virtual void print(const T& x) const = 0;
 
};
 
class derived : public base<double>
{
public:
   virtual void print(const double &x) const {
       std::cout << "derived.print, x = " << x << std::endl;
   }
};
 
 
int main()
{
   base<double> *base = new derived;
 
   base->print(4.5);
 
   return 0;
}
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Март 24, 2012, 14:45 »

Да легко:
Что легко-то? Улыбающийся В Вашем примере virtual хоть есть хоть нету - все работает одинаково, виртуальный механизм никак не используется
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #9 : Март 24, 2012, 14:51 »

Да легко:
Что легко-то? Улыбающийся В Вашем примере virtual хоть есть хоть нету - все работает одинаково, виртуальный механизм никак не используется

Как это не используется?
А как же вот эта строчка:
Код
C++ (Qt)
base<double> *base = new derived;
 
И далее:
Код
C++ (Qt)
base->print(4.5);
 

Полиморфизм в чистом виде)


Да, кстатии, архитектура libssc на этом построена)

ЗЫ. Обычно, то, что хочет реализовать автор ветки, делают немного по другому.. Возможно следует покурить в сторону type_traits (классов характеристик)
« Последнее редактирование: Март 24, 2012, 14:53 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Март 24, 2012, 15:24 »

Как это не используется?
А как же вот эта строчка:
Код
C++ (Qt)
base<double> *base = new derived;
 
И далее:
Код
C++ (Qt)
base->print(4.5);
 

Полиморфизм в чистом виде)
Так он заканчивается на <double>, напр
Код
C++ (Qt)
base<double> *baseD = new derivedD;
base<float> *baseF = new derivedF;
 
Хотя оба могут делать print - это разные методы (полиморфные но никак не связанные между собой) и использовать их в общем виртуальном механизме не удается. Эффект virtual равен нулю  

ЗЫ. Обычно, то, что хочет реализовать автор ветки, делают немного по другому.. Возможно следует покурить в сторону type_traits (классов характеристик)
Расскажите, мне тоже интересно
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Март 24, 2012, 16:16 »

Цитировать
Так он заканчивается на <double>, напр
Код
C++ (Qt)
base<double> *baseD = new derivedD;
base<float> *baseF = new derivedF;
 

Хотя оба могут делать print - это разные методы (полиморфные но никак не связанные между собой) и использовать их в общем виртуальном механизме не удается. Эффект virtual равен нулю  

Так сами классы base<double> и base<float> - это два совершенно разных класса с точки зрения компилятора.

Код
C++ (Qt)
Расскажите, мне тоже интересно
 
Об этом уже много написано.. Типичный пример это std::numeric_limits<T>

Если в двух словах:
Код
C++ (Qt)
template <class T>
struct my_type_traits
{
typedef T type;
typedef T* pointer_type;
typedef const T& const_reference;
typedef T& reference;
 
// Может содержать свой методы, но обычно это статические функции..
 
static void some_method(const_reference x) { std::cout << "my_type_traits::some_method, x =" << x << std::endl;  }
//...
};
 
// Можно сделать специализациию на my_type_traits или написать свой
template<>
struct my_type_traits<double>
{
//...
static void some_method(const_reference x) { std::cout << " my_type_traits<double>, x = " << x << std::endl; }
};
 
template <class T, class Traits = my_traits<T> >
class my_class
{
public:
typedef typename Traits::type type;
typedef typename Traits::pointer_type pointer_type;
typedef typename Traits::const_reference const_reference;
typedef typename Traits::reference reference;
//...
type my_method(const_reference x) {
   Traits::some_method(x);
  //...  
   return x;
}
// Ну и т.д.
};
 
//Используется это так
 
my_class<int> mi;
mi.some_method(2);
 
my_class<double> md;
md.some_method(3.14);
 
 
Это делает код более гибким, поскольку можно отдельно (независимо) писать свои типы характеристик, определяя их индивидуальное поведение, причём интерфейс класса, который их использует остаётся неизменным.

В книжке "Философия С++" (2 часть) есть хороший пример, как это используется..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Андрей
Гость
« Ответ #12 : Март 24, 2012, 18:38 »

Спасибо. Скомпилил. На удивление больше ошибок не было. Хотя правил код, который писал в последний раз неделю назад, правил особо не вдумываясь:-)))

Только немного неудобно, когда всё в одном h-нике. Хорошо, хоть VWordIndex описал в другом h-нике отдельно от его срр кода.

Созрею, почитаю - сделаю через traits.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #13 : Март 24, 2012, 21:04 »

Спасибо. Скомпилил. На удивление больше ошибок не было. Хотя правил код, который писал в последний раз неделю назад, правил особо не вдумываясь:-)))

Только немного неудобно, когда всё в одном h-нике. Хорошо, хоть VWordIndex описал в другом h-нике отдельно от его срр кода.

Созрею, почитаю - сделаю через traits.

Да может в вашей задаче нужно делать не обязательно через traits.. Всё зависит от постановки конкретной задачи.
Но почитать об этом патерне всё равно стоит)) 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
mutineer
Гость
« Ответ #14 : Март 25, 2012, 13:07 »

Решил шаблоны освоить. Написал шаблон. Шаблон типонезависимый и не знает полей классов Ti и Tp. Описал частично его методы, понял что кое-где гораздо удобней, когда класс знает типы классов Ti и Tp.
 
Решил что нужно от него наследовать класс и в классе переопределять некоторые методы в зависимости от типов.

Мне кажется, или тут правда можно обойтись специализацией шаблона?
Записан
Страниц: [1] 2 3 ... 6   Вверх
  Печать  
 
Перейти в:  


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