|
|
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
Столкнулся со следующей проблемой: предположим что у нас есть простой шаблонный класс template <class Type> class Test { protected: Type m_val; } Нам необходимо создать контейнер vector, содержащий экземпляры класса Test, причем тип Type может быть разным. Как это сделать? vector<Test<int> > m_arr; - тогда можно запихнуть Test имеющий Type = int, а мне нужно чтобы еще и другие - например float, char* Так вот - как запихнуть в vector все возможные Test, а не с определенным шаблонным параметром, например, ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 15:01 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 15:33 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
Наверное остается сделать базовый класс и от него отнаследовать все остальные Test-ы а вектор использовать как vector<BaseTest *> и на выходе приводить каждый экземпляр BaseTest к нужному типу. Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 15:39 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
rodb Наверное остается сделать базовый класс и от него отнаследовать все остальные Test-ы а вектор использовать как vector<BaseTest *> и на выходе приводить каждый экземпляр BaseTest к нужному типу. Posted via ActualForum NNTP Server 1.3 В производных классах будут функции типа: int GetValue(); float GetValue(); В базовом классе их не определишь, так как возвращаются разные значения. А как их вызовешь получив базовый класс - ведь механизм виртуальных функции в данном случае не подойдет. Поэтому экземпляр базового класса сначала надо преобразовать к классу наследнику а затем вызвать эти функции Поэтому встает вопрос: как определить какой это класс наследник и преобразовать базовый к нему???? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 15:59 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
"ДимаДВ" >Поэтому встает вопрос: >как определить какой это класс наследник и преобразовать базовый к нему???? class TBase { private: String m_ClassName; public: __fastcall TBase(){m_ClassName = "TBase";};//соответственно в каждом производном классе. __property String ClassName {read = m_ClassName}; }; TBase *a_MyObj = берем указатель из вектора. if(a_MyObj->ClassName == "integer") { приводим к TMyInteger } else if(a_MyObj->ClassName == "float") { приводим к TMyFloat } ...... Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 16:10 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
rodb "ДимаДВ" >Поэтому встает вопрос: >как определить какой это класс наследник и преобразовать базовый к нему???? class TBase { private: String m_ClassName; public: __fastcall TBase(){m_ClassName = "TBase";};//соответственно в каждом производном классе. __property String ClassName {read = m_ClassName}; }; TBase *a_MyObj = берем указатель из вектора. if(a_MyObj->ClassName == "integer") { приводим к TMyInteger } else if(a_MyObj->ClassName == "float") { приводим к TMyFloat } ...... Posted via ActualForum NNTP Server 1.3 Да - так можно но как-то с if'ами не хорошо!! А есть ли возможность имея строку с именем типа преобразовать базовый класс в класс наследник? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 16:20 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
ДимаДВ В производных классах будут функции типа: int GetValue(); float GetValue(); В базовом классе их не определишь, так как возвращаются разные значения. А как их вызовешь получив базовый класс - ведь механизм виртуальных функции в данном случае не подойдет. Поэтому экземпляр базового класса сначала надо преобразовать к классу наследнику а затем вызвать эти функции .... Почему именно так ? Мона например в виртуальном методе возвращать(оперировать) классом, прикрывающий ВСЕ интересующие Вас типы. А у него уже перекрыть ВСЕ операторы равенства, интересующих Вас типов. Т.е. пущай он один знает и умеет превращать из нечто в нечто... тогда будет нечто(в конечном итоге) Код: plaintext 1. 2. 3. с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 16:23 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
kolobok0 ДимаДВ В производных классах будут функции типа: int GetValue(); float GetValue(); В базовом классе их не определишь, так как возвращаются разные значения. А как их вызовешь получив базовый класс - ведь механизм виртуальных функции в данном случае не подойдет. Поэтому экземпляр базового класса сначала надо преобразовать к классу наследнику а затем вызвать эти функции .... Почему именно так ? Мона например в виртуальном методе возвращать(оперировать) классом, прикрывающий ВСЕ интересующие Вас типы. А у него уже перекрыть ВСЕ операторы равенства, интересующих Вас типов. Т.е. пущай он один знает и умеет превращать из нечто в нечто... тогда будет нечто(в конечном итоге) Код: plaintext 1. 2. 3. с уважением (круглый) а есть какая то структура типа LP<чего то там> где можно хранить всякие типы не знаешь как называется ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 16:37 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
kolobok0 ДимаДВ В производных классах будут функции типа: int GetValue(); float GetValue(); В базовом классе их не определишь, так как возвращаются разные значения. А как их вызовешь получив базовый класс - ведь механизм виртуальных функции в данном случае не подойдет. Поэтому экземпляр базового класса сначала надо преобразовать к классу наследнику а затем вызвать эти функции .... Почему именно так ? Мона например в виртуальном методе возвращать(оперировать) классом, прикрывающий ВСЕ интересующие Вас типы. А у него уже перекрыть ВСЕ операторы равенства, интересующих Вас типов. Т.е. пущай он один знает и умеет превращать из нечто в нечто... тогда будет нечто(в конечном итоге) Код: plaintext 1. 2. 3. с уважением (круглый) ты имеешь в виду в базовом классе написать кучу виртуальных функции возвращающих разные типы: virtual int GetVal(); virtual float GetVal(); virtual char* GetVal(); Но ведь он не даст этого сделать - error - функции отличаются только типом возвращаемого значения???? кроме того в одном классе нельзя писать функции ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 16:46 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
ДимаДВ ты имеешь в виду в базовом классе написать кучу виртуальных функции возвращающих разные типы: virtual int GetVal(); virtual float GetVal(); virtual char* GetVal(); Но ведь он не даст этого сделать - error - функции отличаются только типом возвращаемого значения???? кроме того в одном классе нельзя писать функции а теперь правильный вопрос... читать что выше начеркал бум ? далее идёт грубый пример...дальше - включайте Вашу хфантазёрку... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. где то в программе... base* pb = .....; int k = pb->GetVal(); код ессесвенно для передачи смысла..а не один в один.... гэт валью возвращает Вам некий класс. Этот класс имеет перегруженные операторы "=". Дальше надеюсь смысл понятен... (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 17:07 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
Шаблон инстанцируется при компиляции, в этом его удобство. Писать свой класс, возвращающий разные типы - нет смысла, поскольку есть, скажем OLEValue или как там его? И не понятно - зачем такой универсальный класс? Но в рамках заданного вопроса он пишется несложно. class Dumb: public string{ ... string s; public: operator float(){return atof(s.c_str());} operator int(){return atoi(s.c_str());} operator char*(){return s.c_str()} }; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.02.2006, 17:28 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
Не очень понятно (просто не сталкивался) что делает, например: operator int(); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 09:15 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
ДимаДВ Это, Дими, оператор приведения ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 10:15 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
ДимаДВНе очень понятно (просто не сталкивался) что делает, например: operator int(); Это такой хитрый оператор который позволяет обрашаться к переменной типа yourintclass как к int . Работает приблизительно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. но в вашем случае, нужна еще обработка соответствия типов(преобразование) и обработка ошибок при не соответствии типов( преобразовании). Правильно построенная обработка этих ошибок 80% безглючной реализации функционала более высокого уровня. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 11:36 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
Мы с Димой вместе работаем. Проблема немного глубже и ширше, чем просто запихать в вектор класс, а затем приводить его к базовым типам. Суть в чем: в некоем рабочем классе хранятся указатели на параметры BaseParamClass* ptr1; BaseParamClass* ptr2; и указатель на функцию (или на худой конец просто флаг для switch, чтобы выбирать эту функцию). Этот рабочий класс должен уметь делать *ptr1 *= *ptr2; *ptr1 += *ptr2 * (float)m_constvalue; BOOL flag = (*ptr1 == *ptr2); BOOL res = in(ptr1, string_vector); и так далее. Операторы перегружать не обязательно, это просто примеры функций. Если учесть что под BaseParamClass могут лежать IntParam, FloatParam, StringParam, IntVectorParam, FloatVectorParam, StringVectorParam, а также реют призраки DateTimeParam и DecimalParam... Проблема количества перегружаемых функций и безглючного преобразования типов приобретает остроту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 13:55 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
onstat- ДимаДВНе очень понятно (просто не сталкивался) что делает, например: operator int(); Это такой хитрый оператор который позволяет обрашаться к переменной типа yourintclass как к int . Работает приблизительно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. но в вашем случае, нужна еще обработка соответствия типов(преобразование) и обработка ошибок при не соответствии типов( преобразовании). Правильно построенная обработка этих ошибок 80% безглючной реализации функционала более высокого уровня. проблема еще в том что нужно сравнить два экземпляра типы которых неизвестны - не присваивая их ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 14:06 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
RealMaksimus...в некоем рабочем классе хранятся указатели на параметры BaseParamClass* ptr1; BaseParamClass* ptr2; и указатель на функцию (или на худой конец просто флаг для switch, чтобы выбирать эту функцию). Этот рабочий класс должен уметь делать *ptr1 *= *ptr2; *ptr1 += *ptr2 * (float)m_constvalue; BOOL flag = (*ptr1 == *ptr2); BOOL res = in(ptr1, string_vector); и так далее. Операторы перегружать не обязательно, это просто примеры функций. Если учесть что под BaseParamClass могут лежать IntParam, FloatParam, StringParam, IntVectorParam, FloatVectorParam, StringVectorParam, а также реют призраки DateTimeParam и DecimalParam... Проблема количества перегружаемых функций и безглючного преобразования типов приобретает остроту. 1) Что мешает BaseParamClass делегировать выше перечисленный функционал ? Он и по смыслу должен находиться именно там. Ведь его же Вы приравниваете, присваиваете, плюсуете и т.д.. Зачем типизацию высовывать наружу ? Чтоб гиморней ? Или ананизмом позаниматься ? 2) по поводу switch - рекомендую (хотя бы ознакомиться) с книгой Джэфа Элджера "С++ . Библиотека программиста."... найдёте тута (по секрету - есть более жлегантный способ передачи управления!!) 3) Вам никто не мешает делать т.н. "грань кристалла" (по книге). Т.е. некий класс знающий о неких свойствах (типе). И уже при дальнейшей работе использовать его... 4) Кол-во перегруженных операторов равно 8 (все Ваши типы) у ОДНОГО класса (как - описано выше)... Это много ? 5) Глючность из всего выше перечисленного сделать мона, но нуна СИЛЬНО постараться... удачи Вам (круглый) ЗЫ А может ну его нафик этот си плас плас ? Может пригласите со стороны номаного спеца, чтоб просто сделал на пару страницах кода то, что Вам нужно ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 14:58 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
ДимаДВ проблема еще в том что нужно сравнить два экземпляра типы которых неизвестны - не присваивая их У вас проблема с постановкой задачи. Все типы должны быть извесны. И должны приводиться к типа совместимым для сравнения типам иначе вас ждут большие неприянности на этапе тестирования и поддержки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 15:06 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
onstat-И должны приводиться к типа совместимым для сравнения типам иначе вас ждут большие неприянности на этапе тестирования и поддержки. можно оперировать НЕ ИЗВЕСТНЫМИ типами базовых классов, при этом вызывая ПРАВИЛЬНЫЙ обработчик необходимого типа произвольного класса... если задача стоит именно так - то она решаема... и без всяких там глупых свитчей... и именно с помошью механизации "стандартного" си плас пласа... с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 15:09 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
А чем вам variant'ы не нравятся ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 16:17 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
kolobok0 onstat-И должны приводиться к типа совместимым для сравнения типам иначе вас ждут большие неприянности на этапе тестирования и поддержки. можно оперировать НЕ ИЗВЕСТНЫМИ типами базовых классов, при этом вызывая ПРАВИЛЬНЫЙ обработчик необходимого типа произвольного класса... если задача стоит именно так - то она решаема... и без всяких там глупых свитчей... и именно с помошью механизации "стандартного" си плас пласа... с уважением (круглый) Я имел ввиду что реализовывать все виртуалные методы придется автору топика. Значит он должен знать о всех типах с которыми оперирует. Но я не вижу смысла городить допольнительное наследсование. проще все хранить в union и вызывать соответствующие операторы преобразования. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 17:00 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
onstat-Но я не вижу смысла городить допольнительное наследсование. проще все хранить в union и вызывать соответствующие операторы преобразования..... мона...но зачем писать лишний код ? чтоб был ? или потренироваться ? тоды - да, сорьки я не прав. если задача стоит как уменьшить кол-во кода, то совсем НЕ правильно, НЕ использовать механизм виртуальных методов, который делает за Вас вот это: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. согласитесь код содержащий чиссо Код: plaintext 1. будет выглядеть более элегантно и будет содержать меньше кода. а это -> меньше потенциальных ошибок... хотя опять же повторюсь - каждый по своему выбирает уровень сложности реализаци... с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 17:09 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
onstat-...все виртуалные методы придется.... кстати там виртуальный метод - ОДЫН... если Вы хотите вообще ничего не реализовывать - кхм... тут уж я пас...наверное... с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 17:27 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
kolobok0 onstat-...все виртуалные методы придется.... кстати там виртуальный метод - ОДЫН... если Вы хотите вообще ничего не реализовывать - кхм... тут уж я пас...наверное... с уважением (круглый) Не вижу возможности реалзовать через один виртуалній метод потому как типы возвращаемых результатов разные. Как ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 17:48 |
|
||
|
Не тривиальное использование шаблонов
|
|||
|---|---|---|---|
|
#18+
onstat- Не вижу возможности реалзовать через один виртуалній метод потому как типы возвращаемых результатов разные. Как ? (сразу оговорюсь - описываеться механизация, а не точность реализации, посему если будете копировать в студию слова типа бла-бла-бла нуна убрать и заменить на конструктора-деструктора и т.д..) пущай существует класс вэлью... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. пущай будет базовый класс для класса с шаблоном Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. сласс шаблона... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. УРА ! НАШ КЛАСС ! Код: plaintext 1. 2. 3. 4. 5. 6. тогда имеем... xru<z> Z; бла-бла-бла потеряли типизацию...или на событии пришёл безымянный указатель на данные из ГУИ например... Но мы точно знаем - сие есть указатель на базовый класс !!! никак не меньше ! ну и имеем всех, или только указатель - это кому как... base* pb = ....; value v = pb->GetVal(); int k = v.int(); т.к. value всё знает о всех типах, то мона и по просче.... int k = pb->GetVal(); а мона и так... float f = pb->GetVal(); а мона и так... z xz = pb->GetVal(); данный пример имеет немного отличия от приведённого выше в постах. разница в том, что в примере выше речь шла о типах которые способен обрабатывать base.. данная механизация (в посте выше) не плохо ложиться например на связку двух классов (и кстати без виртуал методов) типа RecordSet & Field. Т.е. первый заведует доступом к записи, а второй к полям. Чтоб не писать каждый раз программисту необходимый тип - приведённая выше автоматизация даёт выигрыш и лаконичность... пример из данного поста, на мой взгляд убивает ту задачу в которой требуеться доступ к типизированному экземпляру шаблона. пример скорректирован (за что снимаю шляпу), но аргументов приведённых выше - не дискредитирует... пример есть пример, а не догма. На мой взгляд мона и более красивые способы родить... с уважением (круглый) ЗЫ Про двойную передачу за место свитчей - не буду, лучше уж почитайте книжку :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2006, 19:02 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=33541202&tid=2031824]: |
0ms |
get settings: |
6ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
42ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 213ms |
| total: | 325ms |

| 0 / 0 |
