class A {
public:
virtual ~A() {}
virtual void Method() {}
};
class B1:virtual public A {
public:
virtual void Method() {/*...*/}
/*...*/
};
class B2:virtual public A {
public:
/*...*/
};
class C:public B1, public B2 {
public:
}; // <-- ***int main() {
return 0;
}
в месте
// <-- ***
компилятор (VC7.0) пишет:
a.cpp(21) : warning C4250: 'C' : inherits 'B1::B1::Method' via dominance
a.cpp(10) : see declaration of 'B1::Method'
этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами,
может кто-то подробно разъяснить, что это за варнинг и как с ним боротся.
и сколько ф-ций в таком варианте будет в VMT?
чую я, что где-то поблизости есть грабли
... << RSDN@Home 1.1.3 stable >>
Re: warning C4250: 'class1' : inherits 'class2::member' via
Здравствуйте, yxiie, Вы писали:
Y>этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами, Y>может кто-то подробно разъяснить, что это за варнинг и как с ним боротся. Y>и сколько ф-ций в таком варианте будет в VMT? Y>чую я, что где-то поблизости есть грабли
Структура VMT унаследована от класса A (было бы странно, если бы это не так), и беда в том, что перед классом C стоит проблема: какое из перекрытий использовать. Он берёт первое попавшееся.
Лечится 2 способами:
1) перекрыть метод в классе C, и статически вызывать оттуда метод одного из предков
class C : public B1, public B2
{
public:
virtual Method() { B2::Method(); }
};
2) выбрать метод явно
class C : public B1, public B2
{
public:
using B2::Method;
};
Перекуём баги на фичи!
Re[2]: warning C4250: 'class1' : inherits 'class2::member' v
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, yxiie, Вы писали:
Y>>этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами, Y>>может кто-то подробно разъяснить, что это за варнинг и как с ним боротся. Y>>и сколько ф-ций в таком варианте будет в VMT? Y>>чую я, что где-то поблизости есть грабли
К>Структура VMT унаследована от класса A (было бы странно, если бы это не так), и беда в том, что перед классом C стоит проблема: какое из перекрытий использовать. Он берёт первое попавшееся. К>Лечится 2 способами: К>1) перекрыть метод в классе C, и статически вызывать оттуда метод одного из предков К>
К>class C : public B1, public B2
К>{
К>public:
К> virtual Method() { B2::Method(); }
К>};
К>
К>2) выбрать метод явно К>
К>class C : public B1, public B2
К>{
К>public:
К> using B2::Method;
К>};
К>
а я смогу потом
A* a=new C;
a->Method();
вызвать таким образом метод перекрытый в C?
... << RSDN@Home 1.1.3 stable >>
Re[3]: warning C4250: 'class1' : inherits 'class2::member' v
Начнём с того, что здесь неоднозначное приведение типа. Нужно
A* a = (A*)(B1*)new C();
Про using я погорячился.
Там не происходит перекрытия. Впрочем, это и понятно: метод класса B1 не может работать с this от класса B2.
using служит вместо перегрузки, т.е. статического выбора метода, а не динамического.
Перекуём баги на фичи!
Re[4]: warning C4250: 'class1' : inherits 'class2::member' v
Здравствуйте, yxiie, Вы писали:
Y>этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами, Y>может кто-то подробно разъяснить, что это за варнинг и как с ним боротся.
Y>и сколько ф-ций в таком варианте будет в VMT? Y>чую я, что где-то поблизости есть грабли
Функция будет одна, поскольку если для виртуальной функции не может быть найден final overrider, то код просто не скомпилируется.
Соответсвенно, если ты переопределил Method в C, то C::Method является final overrider — ом, и тут:
A* pa = new c();
pa->Method();
будет вызван именно он.
Любите книгу — источник знаний (с) М.Горький
Re[2]: warning C4250: 'class1' : inherits 'class2::member' v
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, yxiie, Вы писали:
Y>>этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами, Y>>может кто-то подробно разъяснить, что это за варнинг и как с ним боротся.
B>Посмотри здесь
Y>>и сколько ф-ций в таком варианте будет в VMT? Y>>чую я, что где-то поблизости есть грабли B>Функция будет одна, поскольку если для виртуальной функции не может быть найден final overrider, то код просто не скомпилируется. B>Соответсвенно, если ты переопределил Method в C, то C::Method является final overrider — ом, и тут: B>