2012-02-19 4 views
0

Я хочу понять цель виртуальных функций.Что такое виртуальная функция?

Позволяет анализировать этот код, где функция является членом невиртуальном:

Пример 1:

struct A 
{  
    void foo1() { cout << "foo 1 from A \n"; } 
}; 

struct B : A 
{ 
    void foo1() { cout << "foo 1 from B \n"; } 
}; 

int main() 
{ 
    A *a = new B; 
    a->foo1(); // will print "foo 1 from A \n" because A::foo1 isn't virtual 

    B *b = new B; 
    b->foo1(); // will print "foo 1 from B \n" 
} 

Как мы видим выход a->foo1(); будет «foo 1 от A», но я хочу, чтобы функция B выполняла свою собственную функцию foo1. Поэтому я должен переопределить его и сделать виртуальную функцию A::foo1.

Пример 2:

struct A 
{ 
    virtual void foo1() { cout << "foo 1 from A \n"; } 
}; 

struct B : A 
{ 
    void foo1() { cout << "foo 1 from B \n"; } 
}; 

int main() 
{ 
    A *a = new B; 
    a->foo1(); // will print "foo 1 from B \n" 

    B *b = new B; 
    b->foo1(); // will print "foo 1 from B \n" 
} 

Теперь A::foo1 было преодолено и a->foo1() печатает "Foo 1 из B", как мы хотим. Однако, давайте рассмотрим случай, когда класс B имеет некоторые функции, которых нет в А:

Пример 3:

struct A 
{ 
    int a; 
    void foo1() { cout << "foo 1 from A \n"; } 
}; 

struct B : A 
{ 
    int b; 
    void foo1() { cout << "foo 1 from B \n"; } 
    void foo2() { cout << "foo 2 from B \n"; } 
}; 

int main() 
{ 
    A *a = new B; 
    // a->foo2(); // compiler error, a doesn't see foo2 function 
    a->foo1(); 
    // a->b = 1; // compiler error, a doesn't see member variable b 
    a->a = 1; 

    // We aren't going to do B *b = new A; here because that's nonsense 
    B *b = new B; 
    b->foo2(); // ok 
    b->foo1(); // ok 
    b->b = 1; // ok 
    b->a = 1; // ok 
} 

Как мы видим сейчас B не является точной копией; он наследует A и расширяет его некоторыми новыми функциями и переменными. Мы не можем сделать a->foo2() или a->b.

Я думаю, что заявления, подобные A *a = new B;, гораздо более запутанны при чтении или анализе кода, чем B *b = new B;.

Я знаю, что b является указателем на экземпляр B. Не путано ли задаваться вопросом, что такое тип объекта, на который указывает A*?

Итак, мой вопрос: для чего мы можем использовать виртуальные функции?

Я не буду использовать его с производным классом, если у них есть переменные или функции, отсутствующие в базовом классе. Гораздо яснее создать новый объект, используя B *b = new B;, а не A *a = new B;.

Когда я создаю экземпляр B, используя B *b = new B; функции члена не должны быть виртуальными, так как B будет автоматически переопределять A::foo1 со своим собственным foo1.

Поэтому я считаю, что единственное использование виртуальных функций - это когда мы хотим изменить функциональность во время выполнения.

Возможно, это может быть полезно в случае, подобном этому, когда мы хотим изменить выполняемый класс во время выполнения:

A *a; 
B b; 
C c; 

a = &B; 
a->foo1(); 
a = &C; 
a->foo1(); 

Альтернативно, это может быть полезно при переходе аргумента в функцию:

void execute(A *a) 
{ 
    a->foo1(); 
} 

Я что-то пропустил?

+3

Пожалуйста, правильно отформатируйте сообщение. Посмотрите вокруг SO какое-то время, чтобы посмотреть, как это делается, и прочитайте справку по редактированию. –

+3

Мне ясно, что у вас нет книги на C++. Пожалуйста, [исправить это сейчас] (http://jcatki.no-ip.org/fncpp/Resources). –

+0

И, да, четыре месяца достаточно долго, чтобы выяснить, как писать сообщения на SO. Вас уже спрашивали. –

ответ

3

Виртуальные функции - основной способ, которым C++ реализует полиморфизм времени выполнения. Поиск Google для полиморфизма может показать вам, что полезно в этой технике.

0

Виртуальная функция - это способ, которым C++ реализует концепцию полиморфизма.

В C++ простая перегрузка метода используется для полиморфизма времени компиляции, в котором компилятор связывает методы во время компиляции.

И в случае виртуальной функции компилятор будет использовать методы во время выполнения по мере необходимости.

Смежные вопросы