Виртуальные функции и базовый класс
От: Аноним  
Дата: 16.08.12 20:25
Оценка: :))) :))
Здравствуйте! Объясните, плз, почему функции базового класса не привязываются к виртуальным функциям интерфейса?

class I
{
public:
    virtual void f1(void) = 0;
};

class A
{
public:
    void f1(void) { /*...*/ }
};

class B : public A, public I
{
    //...
};

main()
{
    B b;
}


В итоге будет выдана ошибка о том что класс "B" абстрактный т.к. f1 не определена. Но почему? Чисто технически, если бы f1 была определена в "B" а не в "A", то ее код ничем бы не отличался. Так что мешает компилятору ее использовать?
Re: Виртуальные функции и базовый класс
От: Caracrist https://1pwd.org/
Дата: 16.08.12 20:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте! Объясните, плз, почему функции базового класса не привязываются к виртуальным функциям интерфейса?

  Скрытый текст
А>
class I
А>{
А>public:
А>    virtual void f1(void) = 0;
А>};

А>class A
А>{
А>public:
А>    void f1(void) { /*...*/ }
А>};

А>class B : public A, public I
А>{
А>    //...
А>};

А>main()
А>{
А>    B b;
А>}

А>В итоге будет выдана ошибка о том что класс "B" абстрактный т.к. f1 не определена. Но почему? Чисто технически, если бы f1 была определена в "B" а не в "A", то ее код ничем бы не отличался. Так что мешает компилятору ее использовать?



B * b = new B();
A * a = new A();
A * ab = &b;

a->f1(); // f1 не делает virtual call
ab->f1();// f1 не делает virtual call
~~~~~
~lol~~
~~~ Single Password Solution
Re: Виртуальные функции и базовый класс
От: Vamp Россия  
Дата: 16.08.12 20:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте! Объясните, плз, почему функции базового класса не привязываются к виртуальным функциям интерфейса?


А>
class I
А>{
А>public:
А>    virtual void f1(void) = 0;
А>};

А>class A
А>{
А>public:
А>    void f1(void) { /*...*/ }
А>};

А>class B : public A, public I
А>{
А>    //...
А>};

А>main()
А>{
А>    B b;
А>}


А>В итоге будет выдана ошибка о том что класс "B" абстрактный т.к. f1 не определена. Но почему? Чисто технически, если бы f1 была определена в "B" а не в "A", то ее код ничем бы не отличался. Так что мешает компилятору ее использовать?


Это совершенно другая функция. A::f1 определена, все хорошо. Но I::f1 осталась не определенной.
Да здравствует мыло душистое и веревка пушистая.
Re: Виртуальные функции и базовый класс
От: MasterZiv СССР  
Дата: 16.08.12 21:57
Оценка:
class A не наследуется от class I, поэтому
его void f1(void) никак не относится к
функции
virtual void f1(void)
из класса I.

(и кстати A::f1 даже не является виртуальной).

> Чисто технически, если бы f1 была определена в "B" а не в "A", то ее код

> ничем бы не отличался.

Чисто технически если бы она была в B, то зрительно код бы не отличался
(потому что и кода-то там нет сейчас), но также чисто технически
это было бы переопределение I::f1, а поскольку f1 в A, то это просто
разные функции, по случайности имеющие одно и то же имя 'f1'.
Posted via RSDN NNTP Server 2.1 beta
Re: Виртуальные функции и базовый класс
От: johny5 Новая Зеландия
Дата: 17.08.12 04:07
Оценка:
Здравствуйте, Аноним, Вы писали:

Добавлю к предыдущим ораторам, что если хочется использовать именно так, то и наследование должно быть дважды и виртуальным.

class I
{
public:
    virtual void f1(void) = 0;
};

class A : public virtual I
{
public:
    void f1(void) { /*...*/ }
};

class B : public A, public virtual I
{
    //...
};

main()
{
    B b;
}
Re: Виртуальные функции и базовый класс
От: rg45 СССР  
Дата: 17.08.12 14:03
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте! Объясните, плз, почему функции базового класса не привязываются к виртуальным функциям интерфейса?


  Скрытый текст
А>
class I
А>{
А>public:
А>    virtual void f1(void) = 0;
А>};

А>class A
А>{
А>public:
А>    void f1(void) { /*...*/ }
А>};

А>class B : public A, public I
А>{
А>    //...
А>};

А>main()
А>{
А>    B b;
А>}


А>В итоге будет выдана ошибка о том что класс "B" абстрактный т.к. f1 не определена. Но почему? Чисто технически, если бы f1 была определена в "B" а не в "A", то ее код ничем бы не отличался. Так что мешает компилятору ее использовать?


Да, C++ после C# — это как реальность после сна. С пробуждением!
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Виртуальные функции и базовый класс
От: jrk  
Дата: 17.08.12 20:21
Оценка:
Здравствуйте, Caracrist, Вы писали:

...

C>B * b = new B();
C>A * a = new A();
C>A * ab = &b;

a->>f1(); // f1 не делает virtual call
ab->>f1();// f1 не делает virtual call
C>


И? Во-первых компилятор это не скушает все по той же причине.

Во-вторых я не понял что вы хотели сказать. "f1 не делает virtual call" — да, разумеется, и "a" и "ab" это указатели на "A", и там нет virtual call. Но к чему вы это?

В-третьих я могу переписать пример и уже в базовом классе сделать f1 виртуальной, но это ничего не изменит. Хотя вызов уже пойдет через таблицу.
Re[2]: Виртуальные функции и базовый класс
От: jrk  
Дата: 17.08.12 20:22
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Это совершенно другая функция. A::f1 определена, все хорошо. Но I::f1 осталась не определенной.


I::f1 не более чем указатель в таблице вирт. ф-ий. Что мешает ему указывать на A::f1?
Re[2]: Виртуальные функции и базовый класс
От: jrk  
Дата: 17.08.12 20:27
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Чисто технически если бы она была в B, то зрительно код бы не отличался

MZ>(потому что и кода-то там нет сейчас), но также чисто технически
MZ>это было бы переопределение I::f1, а поскольку f1 в A, то это просто
MZ>разные функции, по случайности имеющие одно и то же имя 'f1'.

Чисто технически, раз уж "В" унаследовала "А", то "А" является неотъемлемой частью "В", со всеми вытекающими.

И вообще мне всегда казалось что тело обычной ф-ии ничем не отличается от тела виртуальной. Различается только способ вызова.
Re[2]: Виртуальные функции и базовый класс
От: jrk  
Дата: 17.08.12 20:28
Оценка: -1
Здравствуйте, johny5, Вы писали:

J>Здравствуйте, Аноним, Вы писали:


J>Добавлю к предыдущим ораторам, что если хочется использовать именно так, то и наследование должно быть дважды и виртуальным.


  Скрытый текст
J>
J>class I
J>{
J>public:
J>    virtual void f1(void) = 0;
J>};

J>class A : public virtual I
J>{
J>public:
J>    void f1(void) { /*...*/ }
J>};

J>class B : public A, public virtual I
J>{
J>    //...
J>};

J>main()
J>{
J>    B b;
J>}
J>


Ну наконец реальный собеседник, а не очередной капитан очевидность.

Увы, изначально именно подобная схема и не сработала.

class I1
{
public:
    virtual void f1(void) = 0;
};

class I2 : public I1
{
public:
    virtual void f2(void) = 0;
};

class A : public I1
{
public:
    void f1(void) { /*...*/ }
};

class B : public A, public I2
{
public:
    void f2(void) { /*...*/ }
};

main()
{
    B b;
}


Не работает. Правда вы еще и наследование делаете виртуальным... Но зачем оно здесь?
Re[2]: Виртуальные функции и базовый класс
От: jrk  
Дата: 17.08.12 20:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>Да, C++ после C# — это как реальность после сна. С пробуждением!


Спасибо!

Только маленькая поправочка. C++ после ASM и С — это как сон идиота пускающего слюни и неспособного выйти за рамки заплесневелой концепции придуманной еще при царе горохе.

ЗЫ
Звиняюсь что запостил вам два ответа предназначенных другим участникам. Не привычен мне этот древовидный форум.
Re[3]: Виртуальные функции и базовый класс
От: Vamp Россия  
Дата: 17.08.12 21:45
Оценка:
jrk>I::f1 не более чем указатель в таблице вирт. ф-ий. Что мешает ему указывать на A::f1?
С чего бы вдруг? Почему не на foo в классе baz? Между A::f1 и I::f1 нет ничего общего. Совсем.
Да здравствует мыло душистое и веревка пушистая.
Re[3]: Виртуальные функции и базовый класс
От: Vamp Россия  
Дата: 17.08.12 21:47
Оценка:
jrk>Только маленькая поправочка. C++ после ASM и С — это как сон идиота пускающего слюни и неспособного выйти за рамки заплесневелой концепции придуманной еще при царе горохе.
Не понимаю упрека Не нравится С++ — пиши на С. Можешь даже компилировать свой сишный код C++ компилятором в 90% случаев. И асмовские вставки делать. Какие проблемы?
Да здравствует мыло душистое и веревка пушистая.
Re[3]: Виртуальные функции и базовый класс
От: Ops Россия  
Дата: 18.08.12 05:27
Оценка:
Здравствуйте, jrk, Вы писали:

jrk>Не работает. Правда вы еще и наследование делаете виртуальным... Но зачем оно здесь?


При невиртуальном наследовании производный класс содержит экземпляры всех баз, при виртуальном — один экземпляр на все базы одного типа. RTFM.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Виртуальные функции и базовый класс
От: Caracrist https://1pwd.org/
Дата: 18.08.12 08:18
Оценка:
Здравствуйте, jrk, Вы писали:

jrk>В-третьих я могу переписать пример


я тоже могу переписать свой ответ...
~~~~~
~lol~~
~~~ Single Password Solution
Re[3]: Виртуальные функции и базовый класс
От: MasterZiv СССР  
Дата: 18.08.12 09:52
Оценка:
> Чисто технически, раз уж "В" унаследовала "А", то "А" является неотъемлемой
> частью "В", со всеми вытекающими.
>
> И вообще мне всегда казалось что тело обычной ф-ии ничем не отличается от тела
> виртуальной. Различается только способ вызова.

Ну и ? К чему это всё ?
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Виртуальные функции и базовый класс
От: MasterZiv СССР  
Дата: 18.08.12 09:55
Оценка: +1
> Не работает. Правда вы еще и наследование делаете виртуальным... Но зачем оно здесь?

Затем, чтобы работало. Ты бы пошёл что ли книжку какую почитал...
Объяснять проблемы множественного наследования в С++ в форуме при наличии
тонн литературы по С++ -- занятие неблагодарное.

Я к тому, что это не конкретная проблема, которую ты не можешь решить или не
понимаешь, это -- базовые универсальные знания, которые обсуждать на форуме
бессмысленно.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.