Форум программистов, компьютерный форум CyberForum.ru

virtual функции - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
Tiva
94 / 94 / 1
Регистрация: 25.04.2012
Сообщений: 429
07.02.2013, 18:20     virtual функции #1
я как-то пропустил лекцию по этой теме, и теперь совсем не понимаю назначение этих функций.
может кто поделиться ссылкой и нормальными примерами по этой теме?
и да, я умею пользоваться гуглом, и вводил "virtual функции с++", читал, и не понял ничего
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11836 / 6815 / 770
Регистрация: 27.09.2012
Сообщений: 16,900
Записей в блоге: 2
Завершенные тесты: 1
07.02.2013, 18:29     virtual функции #2
Почитайте еще про наследование и полиморфизм, будут конкретные примеры, как и для чего нужны виртуальные функции
Issues
429 / 364 / 37
Регистрация: 06.08.2012
Сообщений: 961
07.02.2013, 18:39     virtual функции #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, вызовется метод НАСЛЕДНИКА!!!
Пёс
 Аватар для Пёс
228 / 76 / 4
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 18:47     virtual функции #4
Tiva, если функцию объявить виртуальной (virtual) и перегрузить её в классе(ах)-потомке(ах), то при её вызове, через указатель на базовый класс, будут вызываться вызываться именно та версия функции, которая определена в классе-потомке. Иначе была бы вызвана та версия, которая определена в базовом классе....

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

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

есть класс А, в нем функция виртуальна. в классе В она переопределена.
и запись A->функция вызовет функцию из B? а если в классе С она тоже переопределена, как он определит какую вызвать?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11836 / 6815 / 770
Регистрация: 27.09.2012
Сообщений: 16,900
Записей в блоге: 2
Завершенные тесты: 1
07.02.2013, 19:10     virtual функции #6
Компилятор создаст таблицу виртуальных функций и вызов этой функции будет происходить косвенно через vtbl
Пёс
 Аватар для Пёс
228 / 76 / 4
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:12     virtual функции #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" и сравните.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11836 / 6815 / 770
Регистрация: 27.09.2012
Сообщений: 16,900
Записей в блоге: 2
Завершенные тесты: 1
07.02.2013, 19:12     virtual функции #8
Еще раз повторюсь - почитайте про полиморфизм
Пёс
 Аватар для Пёс
228 / 76 / 4
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:26     virtual функции #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");
}
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
07.02.2013, 19:47     virtual функции #10
Пёс, Во первых, никакой утечки памяти нет. Во вторых - не нужно писать такие вещи
Цитата Сообщение от Пёс Посмотреть сообщение
void main()
и уж тем более приводить их в пример новичкам.
Пёс
 Аватар для Пёс
228 / 76 / 4
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 19:56     virtual функции #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");
}
Правда чтоль? Скомпилируйте.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
07.02.2013, 19:58     virtual функции #12
Вы свой предыдущий пример видели? Например строчку
C++
1
virtual ~A()
И я не буду компилировать код, который заведомо не рабочий.
Пёс
 Аватар для Пёс
228 / 76 / 4
Регистрация: 03.02.2013
Сообщений: 311
07.02.2013, 20:00     virtual функции #13
Цитата Сообщение от Toshkarik Посмотреть сообщение
Пёс, Во вторых - не нужно писать такие вещи
и уж тем более приводить их в пример новичкам.
Пишу как в книгах

Добавлено через 1 минуту
Цитата Сообщение от Toshkarik Посмотреть сообщение
Вы свой предыдущий пример видели? Например строчку
C++
1
virtual ~A()
И я не буду компилировать код, который заведомо не рабочий.
1. Код рабочий.
2. Видел свой предыдущий пример. Советую Вам к тому примеру ещё приписку почитать сверху.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
07.02.2013, 20:01     virtual функции #14
Цитата Сообщение от Пёс Посмотреть сообщение
Пишу как в книгах
в каких????
Цитата Сообщение от Пёс Посмотреть сообщение
void main()
дозволяется в С
а в плюсах
C++
1
int main()
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
07.02.2013, 20:05     virtual функции #15
Цитата Сообщение от Пёс Посмотреть сообщение
1. Код рабочий.
Нет, не рабочий, он не скомпилируется как минимум в GCC.

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

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

я так понимаю, смысл появляется когда весь класс и наследники переводятся на виртуальные функции, и только?
Такой указатель нужен, когда вы используете функции, которые будут подходить для всех типов, которые наследуются от A. В этом весь сок полиморфизма.
Tiva
94 / 94 / 1
Регистрация: 25.04.2012
Сообщений: 429
07.02.2013, 20:12  [ТС]     virtual функции #19
Цитата Сообщение от Пёс Посмотреть сообщение
Такой указатель нужен, когда вы используете функции, которые будут подходить для всех типов, которые наследуются от A. В этом весь сок полиморфизма.
кажется я не понимаю эту фразу, точнее "подходить для всех типов" - эта фраза приводит мои мысли к шаблонам, но ведь это не то. чего-то я не до понимаю
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.02.2013, 20:15     virtual функции
Еще ссылки по теме:

Возвращаемое значение virtual функции C++
Virtual и noreturn C++
Protected abstract virtual base pure virtual private destructor C++

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

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
07.02.2013, 20:15     virtual функции #20
Цитата Сообщение от Tiva Посмотреть сообщение
получается из такого указателя (тип А, а память выделена В) - нельзя вызвать методы класса В. Спрашивается - для каких целей нужен полиморфизм(я читал определение на вики, но не понятно все равно, не надо цитировать вики)
у тебя есть класс фигура из него наследуется треугольник и квадрат и круг

ты создал массив фигур (разных)
а теперь надо их все нарисовать
если бы не было полиморфизма то пришлось бы проверять какая у тебя фигура и вызывать её метод рисования
а так все просто
C++
1
2
for(int i=0;i<100;i++)
   figure[i]->Draw();
а полиформизм сам разберется где рисовать круг треугольник или квадрат
Yandex
Объявления
07.02.2013, 20:15     virtual функции
Ответ Создать тему
Опции темы

Текущее время: 07:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru