Ошибка компилятора в хитрой ситуЁвине |
Здравствуйте, гость ( Вход | Регистрация )
Ошибка компилятора в хитрой ситуЁвине |
LuckLess |
19.10.2007, 10:21
Сообщение
#1
|
Студент Группа: Новичок Сообщений: 31 Регистрация: 10.10.2007 Пользователь №: 8 Спасибо сказали: 0 раз(а) Репутация: 0 |
ну... начну с кода...
я думаю.. многие ожидали бы вывода B2.. но 8-я студия выводит B1 а на саамом деле все еще лучше.. фактически этот код не должен компилироватся так как Цитата Then in any well-formed class, for each virtual function declared in that class or any of its direct or indirect base classes there is a unique final overrider that overrides that function and every other overrider of that function. The rules for member lookup (10.2) are used to determine the final overrider for a virtual function in the scope of a derived class but ignoring names introduced by using-declarations. [ Example: struct A { virtual void f(); }; struct B : virtual A { virtual void f(); }; struct C : B , virtual A { using A::f; }; void foo () { C c; c.f (); / / calls B::f, the final overrider c.C::f (); / / calls A::f because of the using-declaration Насколько мне известно ни один компилятор не ведет себя тут правильно. Ну... как же вызвать B2::f... есть несколько варантов.. и все кривоватые(хотя наследование от двух классов, которые наследуются от одинокового интерфейса уже наверняка криво) ) Вариант1. C c; c.C::f (); как в примере из стандарта.. согласитесь не очень удобно так писать - да?))) Вариант2. C c; c.B2::f (); еще хуже чем вариант1 )) Вариант3 class C : public B1, public B2 { public: void f () { return B2::f (); } }; и так для каждой функции..)) тоже не удобно и много лишнего кода.. но зато функцию f можно использовать нормально C c; c.f (); Возможно есть еще варианты... но чтото в голову они не приходят... |
|
|
ViGOur |
19.10.2007, 10:29
Сообщение
#2
|
Мастер Группа: Модератор Сообщений: 3296 Регистрация: 9.10.2007 Из: Москва Пользователь №: 4 Спасибо сказали: 231 раз(а) Репутация: 40 |
Интересно, а где подобной может понадобиться...
Хотя с другой стороны, подобное использование using было введено, значит где-то может быть и пригодиться. |
|
|
Andrew Selivanov |
19.10.2007, 10:49
Сообщение
#3
|
Участник Группа: Участник Сообщений: 249 Регистрация: 9.10.2007 Из: Москва Пользователь №: 3 Спасибо сказали: 15 раз(а) Репутация: 6 |
Прикольно
Временно вкрутив себе мозг разработчика МС я поставил следующий эксперимент:
Как ты думаешь, что выведется на этот раз? А серьезно - как то это напоминает мне паттерн Адаптер... |
|
|
LuckLess |
19.10.2007, 10:51
Сообщение
#4
|
Студент Группа: Новичок Сообщений: 31 Регистрация: 10.10.2007 Пользователь №: 8 Спасибо сказали: 0 раз(а) Репутация: 0 |
дада.. если пеменять местами B1 и B2 все ок) сам замечал
|
|
|
LuckLess |
19.10.2007, 10:52
Сообщение
#5
|
Студент Группа: Новичок Сообщений: 31 Регистрация: 10.10.2007 Пользователь №: 8 Спасибо сказали: 0 раз(а) Репутация: 0 |
А серьезно - как то это напоминает мне паттерн Адаптер... ну.. там б1 и б2 не должны от одного интерфеса наследоваться... чесно говоря не могу сообразить где такое наследование можно применить))) ну... только если взять COM где каждый интерфейс должен быть наследником IUnknown* |
|
|
Andrew Selivanov |
19.10.2007, 12:00
Сообщение
#6
|
Участник Группа: Участник Сообщений: 249 Регистрация: 9.10.2007 Из: Москва Пользователь №: 3 Спасибо сказали: 15 раз(а) Репутация: 6 |
Гы
Кстати возникла еще мысль, для четкости надо бы виртуально пронаследовать B1, B2 от I, дабы копии не таскать... |
|
|
LuckLess |
19.10.2007, 13:10
Сообщение
#7
|
Студент Группа: Новичок Сообщений: 31 Регистрация: 10.10.2007 Пользователь №: 8 Спасибо сказали: 0 раз(а) Репутация: 0 |
если пронаследовать виртуально - тогда не будет компилироватся уже по другой причине.))) там одной виртуальной функции будет соответствовать два разных переопределения ))
а в стандарте !!unique!! final overrider |
|
|
Текстовая версия | Сейчас: 27.12.2024, 6:38 |