Название: Ну очень много приведений Отправлено: Igors от Сентябрь 16, 2011, 06:53 Добрый день
Есть несколько простых template ф-ций, напр Код Беда в том что в момент вызова такой Copy я имею только 2 указателя на базовый тип Base, (а не фактический тип). Возможных типов 4, писать вместо каждой ф-ции 16 не хочется. Также некоторые типы должны быть POD, так что dynamic_cast не проходит (хотя впрочем если бы и проходил - не писать же его 16 раз). Как выкрутиться? Спасибо Название: Re: Ну очень много приведений Отправлено: SimpleSunny от Сентябрь 16, 2011, 13:25 сделать оператор = виртуальным?
Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 16, 2011, 15:08 сделать оператор = виртуальным? Наверное имелось ввиду что оператор = вызывает виртуальный метод. Но во всяком случае набор template ф-ций достаточно большой и оператор ничего не решит, напрКод
Название: Re: Ну очень много приведений Отправлено: Akon от Сентябрь 16, 2011, 19:54 Хотите взаимоисключающих вещей. Если нужно статическое (на этапе комиляции) определение конкретной функции, каждый раз указывайте статические типы при вызове или сделайте 16 перегрузок. Если хотите одну функцию, то все ваши типы должны поддерживать соответствующий интерфейс, типа Clonable (ну или operator=, вызывающий clone):
Код: class Clonable Для поддержки не-Clonable типов (в т.ч. POD) можно сделать шаблон, как у вас; для Clonable - соответствующая перегрузка. Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 17, 2011, 09:31 Если хотите одну функцию, то все ваши типы должны поддерживать соответствующий интерфейс, типа Clonable (ну или operator=, вызывающий clone): Не понял Вашу идею. Метод clone может вернуть только указатель на Clonable, поэтому когда дело дойдет до оператора =, в левой и правой частях будут ссылки на Clonable, т.е. присваивание только базового класса.Название: Re: Ну очень много приведений Отправлено: alexman от Сентябрь 17, 2011, 10:39 Если хотите одну функцию, то все ваши типы должны поддерживать соответствующий интерфейс, типа Clonable (ну или operator=, вызывающий clone): Не понял Вашу идею. Метод clone может вернуть только указатель на Clonable, поэтому когда дело дойдет до оператора =, в левой и правой частях будут ссылки на Clonable, т.е. присваивание только базового класса.Название: Re: Ну очень много приведений Отправлено: Akon от Сентябрь 17, 2011, 10:45 Приведенная мной функция корректна. Там используются массивы указателей (по другому полиморфные или просто разные объекты единым образом (в одном контейнере) не сохранить).
Пример из реальной жизни: Код: class Exception : public std::exception Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 17, 2011, 11:13 ну метод виртуальный. вы же можете его переопределить в наследниках. Но я не могу переопределить тип возвращаемого значения, поэтому в template будет подаваться только Clonable (что в лучшем случае приведет к ошибке компилятора)Код: dst[i] = src[i]->clone(); Код То вообще неясно что делать - ведь базовый класс не имеет члена "x" Название: Re: Ну очень много приведений Отправлено: Akon от Сентябрь 17, 2011, 12:15 Но вы же класс dst не будете объявлясь как базовый, ведь так? Как базовый (Clonable) он будет использоваться в контексте Copy.
Код: class Foo : public Clonable Если же вы хотите в одном контейнере сочетать Foo и Foo1, то никуда не уйти от dynamic_cast. Но такой аспект, как копирование, у вас решается раз и навсегда. Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 18, 2011, 08:48 Но вы же класс dst не будете объявлясь как базовый, ведь так? Как базовый (Clonable) он будет использоваться в контексте Copy. В этом и проблемаКод: std::vector<Foo1*> dst1(Count); Если же вы хотите в одном контейнере сочетать Foo и Foo1, то никуда не уйти от dynamic_cast. Но такой аспект, как копирование, у вас решается раз и навсегда. Сочетать не хочу, мне нужно просто конвертить между 2 контейнерами с разными элементами. Напр все типы элементов совместимы по присваиванию и все имеют член х, но у одного это double, у другого float, int и.т.п. А dynamic_cast. не проблема, если нужен POD тип, то легко добавить ID типа в базовый класс (хоть бы sizeof).Код: class Foo : public Clonable Название: Re: Ну очень много приведений Отправлено: Akon от Сентябрь 19, 2011, 16:44 Цитировать copy видит указатель на Clonable, до членов Foo1 дело не дойдет copy делает виртуальный вызов, и все члены классов наследников будут учтены в их методах createClone()Цитировать ...мне нужно просто конвертить между 2 контейнерами с разными элементами. Напр все типы элементов совместимы по присваиванию и все имеют член х, но у одного это double, у другого float, int и.т.п. Вы хотите присваивать несвязанные (в смысле нет общей базы) типы, но имеющие в интерфейсе сходные части? Код: struct Foo1 Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 19, 2011, 16:57 Вы хотите присваивать несвязанные (в смысле нет общей базы) типы, но имеющие в интерфейсе сходные части? Наоборот :)Беда в том что в момент вызова такой Copy я имею только 2 указателя на базовый тип Base, (а не фактический тип). Название: Re: Ну очень много приведений Отправлено: Akon от Сентябрь 19, 2011, 21:37 Неужели такое
Код: struct Base {} Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 20, 2011, 05:06 Неужели такое С таким как раз проблем нет, т.к. фактические типы (Foo1, Foo2) на руках. Проблемы вот гдеКод: ... Код
Название: Re: Ну очень много приведений Отправлено: Akon от Сентябрь 20, 2011, 20:51 ОК, теперь понятно. При таком объявлении про статический полиморфизм (шаблоны) можно забыть, если у Base нет поля x. Если есть Base::x, то нет проблем:
Код: template <typename T1, typename T2> Название: Re: Ну очень много приведений Отправлено: Igors от Сентябрь 21, 2011, 11:29 Если есть Base::x, то нет проблем: Ну откуда же ему взяться - ведь наследники и задуманы чтобы хранить x и др данные в разных типах/форматах |