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

virtual функции

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

Студворк — интернет-сервис помощи студентам
я как-то пропустил лекцию по этой теме, и теперь совсем не понимаю назначение этих функций.
может кто поделиться ссылкой и нормальными примерами по этой теме?
и да, я умею пользоваться гуглом, и вводил "virtual функции с++", читал, и не понял ничего
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.02.2013, 18:20
Ответы с готовыми решениями:

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

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

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

32
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
07.02.2013, 18:29
Почитайте еще про наследование и полиморфизм, будут конкретные примеры, как и для чего нужны виртуальные функции
0
433 / 368 / 149
Регистрация: 06.08.2012
Сообщений: 961
07.02.2013, 18:39
Если вы не используете наследование, приминение виртуальных функций безсмысленно.
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
Tiva, если функцию объявить виртуальной (virtual) и перегрузить её в классе(ах)-потомке(ах), то при её вызове, через указатель на базовый класс, будут вызываться вызываться именно та версия функции, которая определена в классе-потомке. Иначе была бы вызвана та версия, которая определена в базовом классе....

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

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

есть класс А, в нем функция виртуальна. в классе В она переопределена.
и запись A->функция вызовет функцию из B? а если в классе С она тоже переопределена, как он определит какую вызвать?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
07.02.2013, 19:10
Компилятор создаст таблицу виртуальных функций и вызов этой функции будет происходить косвенно через vtbl
0
 Аватар для Пёс
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:12
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
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
07.02.2013, 19:12
Еще раз повторюсь - почитайте про полиморфизм
0
 Аватар для Пёс
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:26
А вот Вам пример с утечкой памяти. Скомпилируйте так. А потом сотрите "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
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.02.2013, 19:47
Пёс, Во первых, никакой утечки памяти нет. Во вторых - не нужно писать такие вещи
Цитата Сообщение от Пёс Посмотреть сообщение
void main()
и уж тем более приводить их в пример новичкам.
0
 Аватар для Пёс
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:56
Цитата Сообщение от 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
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.02.2013, 19:58
Вы свой предыдущий пример видели? Например строчку
C++
1
virtual ~A()
И я не буду компилировать код, который заведомо не рабочий.
0
 Аватар для Пёс
229 / 76 / 9
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 20:00
Цитата Сообщение от Toshkarik Посмотреть сообщение
Пёс, Во вторых - не нужно писать такие вещи
и уж тем более приводить их в пример новичкам.
Пишу как в книгах

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

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

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

ты создал массив фигур (разных)
а теперь надо их все нарисовать
если бы не было полиморфизма то пришлось бы проверять какая у тебя фигура и вызывать её метод рисования
а так все просто
C++
1
2
for(int i=0;i<100;i++)
   figure[i]->Draw();
а полиформизм сам разберется где рисовать круг треугольник или квадрат
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.02.2013, 20:15
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru