Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/27: Рейтинг темы: голосов - 27, средняя оценка - 4.85
96 / 96 / 21
Регистрация: 25.04.2012
Сообщений: 449
1

virtual функции

07.02.2013, 18:20. Показов 5528. Ответов 32
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
я как-то пропустил лекцию по этой теме, и теперь совсем не понимаю назначение этих функций.
может кто поделиться ссылкой и нормальными примерами по этой теме?
и да, я умею пользоваться гуглом, и вводил "virtual функции с++", читал, и не понял ничего
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.02.2013, 18:20
Ответы с готовыми решениями:

Virtual функции и наследование
Даны 2 класса: class A { public: virtual void sayHi() { std::cout << "A, hi"...

Protected abstract virtual base pure virtual private destructor
Хай, all) Вопрос не для начинающих и дурацкий) В разделе для экспертов публиковать не стал, чтобы...

Возвращаемое значение virtual функции
В инструкции указанно следующее virtual int getHost() создаю у себя в классе int...

Про перегрузку функции и Virtual в классах
В общем вообще запутался с этим ООП... Вот есть в классе функция, перегрузка функции даёт...

32
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
07.02.2013, 18:29 2
Почитайте еще про наследование и полиморфизм, будут конкретные примеры, как и для чего нужны виртуальные функции
0
433 / 368 / 149
Регистрация: 06.08.2012
Сообщений: 961
07.02.2013, 18:39 3
Если вы не используете наследование, приминение виртуальных функций безсмысленно.
http://ru.wikipedia.org/wiki/Виртуальный_метод

Вот нашёл в интернете (ПИСАЛ НЕ Я):

Наглядный пример.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A {
public:
   virtual void go() { cout << "A"; }
};
 
class B : public A {
public:
   void go() { cout << "B"; }
}
 
void main()
{
   A *x = new A();
   A *y = new B();
 
   x->go();
   y->go();
}
Если слово virtual стоит там где оно написано, но на экран будет выведено "AB".
Если убрать слово virtual, то на экран будет выведено "AA".

То есть несмотря на то, что у вас указатель на класс A, вызовется метод НАСЛЕДНИКА!!!
0
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 18:47 4
Tiva, если функцию объявить виртуальной (virtual) и перегрузить её в классе(ах)-потомке(ах), то при её вызове, через указатель на базовый класс, будут вызываться вызываться именно та версия функции, которая определена в классе-потомке. Иначе была бы вызвана та версия, которая определена в базовом классе....

P.S. если Вам не известны некоторые слова, которые я использовал для объяснения, то курите маны
0
96 / 96 / 21
Регистрация: 25.04.2012
Сообщений: 449
07.02.2013, 18:57  [ТС] 5
Цитата Сообщение от Пёс Посмотреть сообщение
Tiva, если функцию объявить виртуальной (virtual) и перегрузить её в классе(ах)-потомке(ах), то при её вызове, через указатель на базовый класс, будут вызываться вызываться именно та версия функции, которая определена в классе-потомке. Иначе была бы вызвана та версия, которая определена в базовом классе....

P.S. если Вам не известны некоторые слова, которые я использовал для объяснения, то курите маны
да слова-то мне все известны... я вот не понимаю...

есть класс А, в нем функция виртуальна. в классе В она переопределена.
и запись A->функция вызовет функцию из B? а если в классе С она тоже переопределена, как он определит какую вызвать?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
07.02.2013, 19:10 6
Компилятор создаст таблицу виртуальных функций и вызов этой функции будет происходить косвенно через vtbl
0
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:12 7
Tiva, так, ещё раз....

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
class A
{
public:
    virtual void F()
    {
        cout << "A::F()" << endl;
    }
};
class B : public A
{
public:
    void F()
    {
        cout << "B::F()" << endl;
    }
};
void main()
{
    A* pointerTypeA = new B(); /*Прошу обратить внимание на тип указателя и на тип объекта*/
    pointerTypeA->F();
    system("pause");
}
Попробуйте так. А потом сотрите "virtual" и сравните.
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
07.02.2013, 19:12 8
Еще раз повторюсь - почитайте про полиморфизм
0
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:26 9
А вот Вам пример с утечкой памяти. Скомпилируйте так. А потом сотрите "virtual", и поймёте где появилась утечка.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;
class A
{
    char* p1;
public:
 
    A()
    {
        p1 = new char[10];
    }
    virtual ~A()
    {
        cout << "~A()" << endl;
        delete[] p1;
    }
};
class B : public A
{
    char* p2;
public:
    B()
    {
        p2 = new char[20];  
    }
 
    ~B()
    {
        cout << "~B()" << endl;
        delete[] p2;
    }
};
void main()
{
    A* pointerTypeA = new B(); /*Прошу обратить внимание на тип указателя и на тип объекта*/
    delete pointerTypeA;
    system("pause");
}
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.02.2013, 19:47 10
Пёс, Во первых, никакой утечки памяти нет. Во вторых - не нужно писать такие вещи
Цитата Сообщение от Пёс Посмотреть сообщение
void main()
и уж тем более приводить их в пример новичкам.
0
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:56 11
Цитата Сообщение от Toshkarik Посмотреть сообщение
Пёс, Во первых, никакой утечки памяти нет
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;
class A
{
    char* p1;
public:
 
    A()
    {
        p1 = new char[10000];
    }
    ~A()
    {
        cout << "~A()" << endl;
        delete[] p1;
    }
};
class B : public A
{
    char* p2;
public:
    B()
    {
        p2 = new char[20000];  
    }
 
    ~B()
    {
        cout << "~B()" << endl;
        delete[] p2;
    }
};
void main()
{
    while(1)
    {
        A* pointerTypeA = new B[1000];    /*Прошу обратить внимание на тип указателя и на тип объекта*/
        delete[] pointerTypeA;
    }
    system("pause");
}
Правда чтоль? Скомпилируйте.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.02.2013, 19:58 12
Вы свой предыдущий пример видели? Например строчку
C++
1
virtual ~A()
И я не буду компилировать код, который заведомо не рабочий.
0
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 20:00 13
Цитата Сообщение от Toshkarik Посмотреть сообщение
Пёс, Во вторых - не нужно писать такие вещи
и уж тем более приводить их в пример новичкам.
Пишу как в книгах

Добавлено через 1 минуту
Цитата Сообщение от Toshkarik Посмотреть сообщение
Вы свой предыдущий пример видели? Например строчку
C++
1
virtual ~A()
И я не буду компилировать код, который заведомо не рабочий.
1. Код рабочий.
2. Видел свой предыдущий пример. Советую Вам к тому примеру ещё приписку почитать сверху.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
07.02.2013, 20:01 14
Цитата Сообщение от Пёс Посмотреть сообщение
Пишу как в книгах
в каких????
Цитата Сообщение от Пёс Посмотреть сообщение
void main()
дозволяется в С
а в плюсах
C++
1
int main()
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.02.2013, 20:05 15
Цитата Сообщение от Пёс Посмотреть сообщение
1. Код рабочий.
Нет, не рабочий, он не скомпилируется как минимум в GCC.

Цитата Сообщение от Пёс Посмотреть сообщение
2. Видел свой предыдущий пример. Советую Вам к тому примеру ещё приписку почитать сверху.
Когда читал, не увидел последнюю фразу, ее или не было тогда, или я просмотрел ее. Если не увидел я - то извиняюсь.
1
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 20:08 16
Цитата Сообщение от ValeryS Посмотреть сообщение
дозволяется в С
а в плюсах
C++
1
int main()
спасибо, об этом я не знал. в книгах часто видел такую запись.
0
96 / 96 / 21
Регистрация: 25.04.2012
Сообщений: 449
07.02.2013, 20:08  [ТС] 17
Цитата Сообщение от Пёс Посмотреть сообщение
Tiva, так, ещё раз....

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
class A
{
public:
    virtual void F()
    {
        cout << "A::F()" << endl;
    }
};
class B : public A
{
public:
    void F()
    {
        cout << "B::F()" << endl;
    }
};
void main()
{
    A* pointerTypeA = new B(); /*Прошу обратить внимание на тип указателя и на тип объекта*/
    pointerTypeA->F();
    system("pause");
}
Попробуйте так. А потом сотрите "virtual" и сравните.
получается из такого указателя (тип А, а память выделена В) - нельзя вызвать методы класса В. Спрашивается - для каких целей нужен полиморфизм(я читал определение на вики, но не понятно все равно, не надо цитировать вики)
или для каких целей можно использовать этот "недоуказатель"?

я так понимаю, смысл появляется когда весь класс и наследники переводятся на виртуальные функции, и только?
0
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 20:10 18
Цитата Сообщение от Tiva Посмотреть сообщение
получается из такого указателя (тип А, а память выделена В) - нельзя вызвать методы класса В. Спрашивается - для каких целей нужен полиморфизм(я читал определение на вики, но не понятно все равно, не надо цитировать вики)
или для каких целей можно использовать этот "недоуказатель"?

я так понимаю, смысл появляется когда весь класс и наследники переводятся на виртуальные функции, и только?
Такой указатель нужен, когда вы используете функции, которые будут подходить для всех типов, которые наследуются от A. В этом весь сок полиморфизма.
1
96 / 96 / 21
Регистрация: 25.04.2012
Сообщений: 449
07.02.2013, 20:12  [ТС] 19
Цитата Сообщение от Пёс Посмотреть сообщение
Такой указатель нужен, когда вы используете функции, которые будут подходить для всех типов, которые наследуются от A. В этом весь сок полиморфизма.
кажется я не понимаю эту фразу, точнее "подходить для всех типов" - эта фраза приводит мои мысли к шаблонам, но ведь это не то. чего-то я не до понимаю
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
07.02.2013, 20:15 20
Цитата Сообщение от Tiva Посмотреть сообщение
получается из такого указателя (тип А, а память выделена В) - нельзя вызвать методы класса В. Спрашивается - для каких целей нужен полиморфизм(я читал определение на вики, но не понятно все равно, не надо цитировать вики)
у тебя есть класс фигура из него наследуется треугольник и квадрат и круг

ты создал массив фигур (разных)
а теперь надо их все нарисовать
если бы не было полиморфизма то пришлось бы проверять какая у тебя фигура и вызывать её метод рисования
а так все просто
C++
1
2
for(int i=0;i<100;i++)
   figure[i]->Draw();
а полиформизм сам разберется где рисовать круг треугольник или квадрат
1
07.02.2013, 20:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.02.2013, 20:15
Помогаю со студенческими работами здесь

Значение delete в объявлении virtual функции
Привет всем! Закрываю дыры в знаниях C++:). Требуется помощь. Есть такой код: class SomeClass {...

Что изменяется, когда я у виртуальной функции в наследнике пишу virtual
Мужики, такой вопрос: что изменяется, когда я у виртуальной функции в наследнике пишу virtual?...

Зачем в конце объявления виртуальной функции ноль: virtual void show()=0 ?
Здравствуйте. Что значат строки? И есть ли в них разница? virtual void show()=0; virtual void...

Виртуальные функции (нужно ли во всех производных классах писать слово virtual?)
Нужно ли во всех производных классах писать слово virtual? Или достаточно только один раз в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru