![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| CPlusPlusFAN |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 315 Регистрация: 1.11.2005 Где: Воронеж Репутация: нет Всего: нет |
Имеется класс:
Ещё есть 2 класса:
И класс-контейнер:
Класс cont содержит элемент базового класса cl и имя действительного класса ClassName. А вот оператор стрелка возвращает указатель на elem. Но вот проблема, с помощью оператора можно получить доступ только к базовому классу. А можно ли получить доступ (без явного приведения) именно к полю elem как к классу cl1 или cl2 (в зависимости от того, какой конструктор выбран)? Я понимаю, что elem формируется во время выполнения, но всё же... |
||||||
|
|||||||
| chipset |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Шаблоны, специализация конструктора и dynamic_cast спасут тебя.
--------------------
|
|||
|
||||
| CPlusPlusFAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 315 Регистрация: 1.11.2005 Где: Воронеж Репутация: нет Всего: нет |
Спасибо, я тоже думал про шаблоны, а можно пример?
|
|||
|
||||
| chipset |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Примерно так.
или так
--------------------
|
||||||
|
|||||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
зачем приводить все к T* а затем возвращать заново cl*? кроме того ты уверен, что cl - полифорфный, чтобы применять dynamic_cast? Это сообщение отредактировал(а) MAKCim - 21.2.2006, 09:28 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| chipset |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Ступил
Нет. А у тебя есть метода получше? --------------------
|
||||
|
|||||
| threef |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 27.10.2005 Где: Запорожье Репутация: 9 Всего: 10 |
Вообще-то это типичный пример полиморфизма, ИМХО применять преобразования - извращение натурально. Виртуальные методы доступа к элементам класса описываются в базовом, перекрываются в производных. Кстати, перегрузка
ссылки - типичный пример, но можно и так:
|
|||
|
||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
может это
List - список типов производных от Base классов длины равной кол-ву перегруженных версий конструктора Base - базовый класс index_type - определяет тип в списке типов по его порядковому номеру в нем convert - определяет является ли U - производным от Base cnvt - статический метод convert, пытается сконвертировать pointer в U* про списки типов см. Александреску -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| CPlusPlusFAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 315 Регистрация: 1.11.2005 Где: Воронеж Репутация: нет Всего: нет |
У меня начинает складываться впечатление, что эта задача вообще не разрешима без приведения типа извне...
За время решения задачи мне на ум пришло 3 возможных метода: 1) общий потомок. Класс, унаследованный от 2-х потомков класса cl. Этот метод не пашет, т.к. поля одного из родительских классов будут неинициализированы. 2) шаблон. Оформление оператора-селектора в виде шаблона, но при этом при доступе к классу требуется явно задать тип в <>. 3) виртуальные методы возврата. Возврат полей класса виртуальной(ыми) функцией(ями). Если возвращать по одному полю из функции, то количество функций будет меняться при добавлении/удалении полей, да и при несовпадении количества и типов полей у разных потомков это приводит в тупик. Если возвращать структуры полей, то для всех потомков будет 1 структура на всех (т.е. общая), но при инициализации часть полей будет неопределена (и пользователь может перепутать поля, особенно, если их много). Итак, все 3 способа привели в тупик... Может, у кого-то есть ещё предложения??? |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Это потому, что ты пытаешься родить общую теорию всего. Задачу поставь поконкретней... А вообще приведенный тобой класс cont напоминает попытку сваять smart-pointer, т.е. псевдо-указатель, инкапсулирующий управление памятью. Если дело только в этом, то задача давно успешно решена товарищами Мейерсом, Александреску,etc... Да вот хотя бы boost::smart_pointer... -------------------- ... |
|||
|
||||
| CPlusPlusFAN |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 315 Регистрация: 1.11.2005 Где: Воронеж Репутация: нет Всего: нет |
Итак уже поставил, конкретней некуда: необходимо, чтобы указатель elem в классе cont возвращал указатель на корректный класс (cl1 или cl2). Т.е., чтобы пользователю не приходилось делать что-то вроде:
Это сообщение отредактировал(а) CPlusPlusFAN - 21.2.2006, 21:59 |
||||
|
|||||
| np9mi7 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 553 Регистрация: 17.8.2003 Где: Volgograd, Russia Репутация: 5 Всего: 10 |
Это смотря как задачу поставить: 1.) Если действительный тип не известен на этапе компиляции, то придеться делать dynamic_cast либо определять общий интерфейс; 2.) Если действительный тип известен на этапе компиляции, то использование шаблонов даст красивое решение, без такого ужаса:
Это сообщение отредактировал(а) np9mi7 - 22.2.2006, 00:24 |
||||
|
|||||
| CPlusPlusFAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 315 Регистрация: 1.11.2005 Где: Воронеж Репутация: нет Всего: нет |
np9mi7, действительный тип неизвестен, ведь пользователь сам волен выбирать, какой из конструкторов выбрать:
А думаете мне это нравится? А вот отсюда можно поподробней? |
|||
|
||||
| np9mi7 |
|
||||||||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 553 Регистрация: 17.8.2003 Где: Volgograd, Russia Репутация: 5 Всего: 10 |
CPlusPlusFAN, перед тем как всё это прочтешь, поймешь всю сложность задачи и уродливость любого из его решений - задай себе вопрос "Тип точно не известен на этапе компиляции?"
Итак, если тебе тип не известен, то стандартнее делать так: 1) dynamic_cast: Базовый тип:
Определение потомков:
Используй почти стандартный boost::shared_ptr вместо написания своего owner - а
Функция которая будет работать с конткетным типом, имея только абстрактный тип:
2) Общий интерфейс Базовый тип:
Определение потомков:
Используй почти стандартный boost::shared_ptr вместо написания своего owner - а
Функция которая будет работать с конткетным типом, имея только абстрактный тип (необходимо следить за исключениями):
Это сообщение отредактировал(а) np9mi7 - 24.2.2006, 01:11 |
||||||||||||||||
|
|||||||||||||||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |