Я хочу понять цель виртуальных функций.Что такое виртуальная функция?
Позволяет анализировать этот код, где функция является членом невиртуальном:
Пример 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();
}
Я что-то пропустил?
Пожалуйста, правильно отформатируйте сообщение. Посмотрите вокруг SO какое-то время, чтобы посмотреть, как это делается, и прочитайте справку по редактированию. –
Мне ясно, что у вас нет книги на C++. Пожалуйста, [исправить это сейчас] (http://jcatki.no-ip.org/fncpp/Resources). –
И, да, четыре месяца достаточно долго, чтобы выяснить, как писать сообщения на SO. Вас уже спрашивали. –