![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Chaos A.D. |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 172 Регистрация: 16.1.2005 Где: 09 RUS Репутация: 6 Всего: 7 |
В библиотеке Loki в реализации паттерна AbstractFactory есть такой код...
Мне не совсем понятно, зачем делать срез в следующем коде - Unit<T>& unit = *this;. Ясно одно - без него вызов виртуальной функции DoCreate у Unit<T> считается неоднозначным. Но почему? --------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Я, к сожалению, не знаю, как устроена библиотеку Loki, но раз вызов может быть неоднозначным, то, возможно, где-то в иерархии наследования AbstractFactory встречается либо множественное наследование от Unit (или его базового класса), либо кто-то еще в иерархии имеет метод DoCreate. А может AbstractFactory вовсе не наследуется от Unit, а просто имеет оператор приведения...
-------------------- ... |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Earnest
Так точно. GenScatterHierarchy наследуется от Unit, специализированного каждым типом из списка типов TList. Все подробно у Александреску в "Modern C++ Design" расписано. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Точно, у Александреску я про это и читала - то-то я смотрю, слова все какие-то знакомые
![]() Однако мне всегда казалось, что реализовать основные паттерны в виде шаблонов - интересно, конечно, теоретически - в смысле очередного доказательства всемогущества C++. Но с практической точки зрения, лучше некоторые вещи делать под свой проект самим... ИМХО, конечно. -------------------- ... |
|||
|
||||
LPBOY |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
Что значит "срез"? --------------------
Каждый человек по-своему прав, а по-моему нет... |
|||
|
||||
comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
Сорри за оффтопик, но где брать доки по Loki. Кроме solarix.ru - там неполная. Я че-т у Александревску не нашел
![]() |
|||
|
||||
Chaos A.D. |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 172 Регистрация: 16.1.2005 Где: 09 RUS Репутация: 6 Всего: 7 |
А кстати, почему так получается, что если у нас есть класс A с виртуальной функцией MakeSomething(int), и класс B с виртуальной функцией с аналогичным именем, но с параметром char, то при выведении класса AB из A и B, вызов AB::MakeSomething('x') или AB::MakeSomething(4325) считается неоднозначным?
Добавлено @ 20:01
Вообще в моем примере я ошибся, это не то, что называется срезом. А вообще, срез - это когда объект базового класса создается из производного. Например, если кидать исключение класса B, а поймать по значению класса A, который является базовым для B, данные из B, не содержащиеся в A потеряются. Чтобы этого избежать, нужно ловить исключения например по ссылке. Это только пример среза. Добавлено @ 20:06
Имхо после книги Александреску "Modern C++ Design" про Loki вряд-ли можно что-нибудь сказать. Это сообщение отредактировал(а) Chaos A.D. - 30.7.2005, 20:09 --------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest |
||||
|
|||||
Chaos A.D. |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 172 Регистрация: 16.1.2005 Где: 09 RUS Репутация: 6 Всего: 7 |
Я нашел крайне удобным шаблонный класс Functor, реализацию паттерна Command, по моему. Так-же очень удобно, и, имхо, на все случаи жизни, реализован Smart Pointer. Классно написан Singleton. Если бы мне надо было бы написать функтор самому, я бы попытался переписать его так же, как написал его Александреска. По моему, функторы у него просто образцово-показательные ![]() --------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Насколько я понимаю, overload resolution (13.3) выполняется, только если функция-член была найдена однозначно (Member name lookup, 10.2). Вроде так. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
LPBOY |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
Для того чтобы перегрузка функций имела место надо чтобы все функции находились в одной и той же области видимости. В твоем примере они находятся в разных областях. Отсюда вывод: помести их в область класса AB с помощью using объявлений, тогда перегрузка будет работать. Иначе надо просто явно указывать базовый класс: A::MakeSomething или B::MakeSomething. Это сообщение отредактировал(а) LPBOY - 30.7.2005, 21:16 --------------------
Каждый человек по-своему прав, а по-моему нет... |
|||
|
||||
Chaos A.D. |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 172 Регистрация: 16.1.2005 Где: 09 RUS Репутация: 6 Всего: 7 |
Странные вещи творятся... В Евангилие от Страуструпа я докопался вот до чего : "Разрешение перегрузки не пересекает границ областей видимости классов. В частности, неоднозначности между функциями из различных базовых классов не разрешаются на основе типов аргументов.". Это можно считать исчерпывающим ответом на мой предыдущий вопрос. Но если ввести обе функции из базовых классов в область видимости производного класса при помощи using-объявления, все становится на свои места... Однако не все так мажорно. Если мои функции из базовых классов виртуальные, вызывается всегда только одна, причем её фактический параметр, похоже, reinterpret_cast-ится к типу формального параметра. Очень удивило меня, когда функция, принимающая std::string, вдруг приводила его к типу double. Как я понимаю, у класса, подобного моему из примера, два указателя на таблицы виртуальных функций, но как это сказывается на виртуальном вызове из моего примера? Как там это оговорено в стандарте?
--------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Chaos A.D.
Можно код в студию? И версию компилятора. Если я правильно понял проблему, VC 7.1 подобную ситуацию отрабатывает нормально. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Chaos A.D. |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 172 Регистрация: 16.1.2005 Где: 09 RUS Репутация: 6 Всего: 7 |
Void, ты прав, дело в компилере. Глючный Борландовский компилер компилил с ошибками, неполенился скомпилить это дело в линухе с G++, все заработало. Попробуйте, у кого есть компилер от Borland, скомпилить этот код. А как подобный код обрабатывают другие компилеры (Comeau, Intel-овский)?
--------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest |
|||
|
||||
LPBOY |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
Попробовал...
Проверил в своих MSVC 7.1, Digital Mars 8.4.3, работает нормально. Так что это конечно баг дебилдера. --------------------
Каждый человек по-своему прав, а по-моему нет... |
||||
|
|||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Chaos A.D.
VC 7.1, VC 8.0 beta 2, Intel 7.1 (Win), GCC 3.4.2 (MinGW), даже малоизвестный DigitalMars 8.41 компилят нормальный код (по поводу Comeau я даже сомневаться не буду). А это угребище Borland C++ 5.6 aka BCB6 - нет! Всерьез не завидую тем, кто вынужден иметь с ним дело. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |