warning C4250: 'class1' : inherits 'class2::member' via domi
От: yxiie Украина www.enkord.com
Дата: 08.10.04 14:59
Оценка:
Моя упрощенная иерархия выглядит так:

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
От: Кодт Россия  
Дата: 08.10.04 15:09
Оценка:
Здравствуйте, 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 Украина www.enkord.com
Дата: 08.10.04 17:59
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 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
От: Кодт Россия  
Дата: 11.10.04 09:37
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>а я смогу потом

Y>A* a=new C;
a->>Method();

Y>вызвать таким образом метод перекрытый в C?

Начнём с того, что здесь неоднозначное приведение типа. Нужно
A* a = (A*) (B1*) new C();


Про using я погорячился.
Там не происходит перекрытия. Впрочем, это и понятно: метод класса B1 не может работать с this от класса B2.
using служит вместо перегрузки, т.е. статического выбора метода, а не динамического.
Перекуём баги на фичи!
Re[4]: warning C4250: 'class1' : inherits 'class2::member' v
От: Bell Россия  
Дата: 11.10.04 09:55
Оценка:
Здравствуйте, Кодт, Вы писали:


К>Начнём с того, что здесь неоднозначное приведение типа. Нужно

К>
К>A* a = (A*) (B1*) new C();
К>


С чего это оно неоднозначное? А — виртуальный базовый класс, и никакой неоднозначности тут нет.
Любите книгу — источник знаний (с) М.Горький
Re: warning C4250: 'class1' : inherits 'class2::member' via
От: Bell Россия  
Дата: 11.10.04 10:17
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами,

Y>может кто-то подробно разъяснить, что это за варнинг и как с ним боротся.

Посмотри здесь
Автор: Bell
Дата: 13.09.04


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
От: yxiie Украина www.enkord.com
Дата: 11.10.04 11:40
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, yxiie, Вы писали:


Y>>этот варнинг говорит, что у родителей класса есть методы с одинаковыми именами,

Y>>может кто-то подробно разъяснить, что это за варнинг и как с ним боротся.

B>Посмотри здесь
Автор: Bell
Дата: 13.09.04


Y>>и сколько ф-ций в таком варианте будет в VMT?

Y>>чую я, что где-то поблизости есть грабли
B>Функция будет одна, поскольку если для виртуальной функции не может быть найден final overrider, то код просто не скомпилируется.
B>Соответсвенно, если ты переопределил Method в C, то C::Method является final overrider — ом, и тут:
B>
B>A* pa = new c();
pa->>Method();
B>

B>будет вызван именно он.

пасиба, именно это я и хотел узнать.
... << RSDN@Home 1.1.3 stable >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.