Тема: Для чого створювати віртуальні функції?*
не можу зрозуміти навіщо створювати віртуальні функції. Наскільки я зрозумів якщо існує вказіник обєкт класа який наслідує базовия клас в якому є віртуальні методи то вони не будуть презапсані?
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → Для чого створювати віртуальні функції?*
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися
не можу зрозуміти навіщо створювати віртуальні функції. Наскільки я зрозумів якщо існує вказіник обєкт класа який наслідує базовия клас в якому є віртуальні методи то вони не будуть презапсані?
Почитайте про поліморфізм. Дуже складно пояснити, що це у кількох словах.
Віртуальність дозволяє здійснювати перевантаження методів класу зі збереженням принципу ієрархії класів. Базовий клас - це деякий "спільний набір рис" для різних типів даних, тому, наприклад, і до європейця, і до американця можна звернутися "людино!". Однак кожен з них по-різному харчується. У цьому разі метод toEat() може бути таким:
void Human::toEat(Food e)
{
while(!noMoreNeed())
{
swallow(e);
digest(e);
}
}
void American::toEat(Food e)
{
try
{
while(true)
{
swallow(e);
}
}
catch(noStomackSpace n)
{
digest(e);
}
}
Тож за цим кодом американець має власний алгоритм споживання, тоді як "класичний європеєць" задовольняється і "природним способом харчування". Тому, якщо до американця звернутися "гей ти, людино, дуй на палубу!", то його спосіб харчування, очевидно, буде "природним". А якщо "пане американцю, прошу на палубу!", то тоді харчування буде за "суто американським" способом, тож віртуально він харчується та'як звичайні люди, а реально - по-американськи.
Будь ласка напишіть простенький код з використання віртуальних функцій.
Приклад із реального життя: в програмах, що займаються обліком товарів на складі часто використовуються файли у форматі MMO та (його нащадку) XMMO. Ці формати мають багато чого спільного, але є і відмінності. Ми не хочемо копіпастити код, що реалізує спільний функціонал у два різних класи (бо це буде жах з точки зору підтримки), а хочемо щоб він увесь був в одному місці. У цьому випадку один із найкращих варіантів - це наслідування. Ми пхаємо загальний код у клас предок, а усі відмінності реалізовуємо у нащадках. А що нам робити, якщо загальному коду необхідно викликати спеціалізовану функцію нащадка? - Ми просто викликаємо віртуальну функцію, а її кожен нащадок реалізує самостійно.
Будь ласка напишіть простенький код з використання віртуальних функцій.
class Human
{
public:
virtual void toEat(Food e)
{
while(!noMoreNeed())
{
swallow(e);
digest(e);
}
}
};
class American: virtual public Human
{
public:
void toEat(Food e)
{
try
{
while(true)
{
swallow(e);
}
}
catch(noStomackSpace n)
{
digest(e);
}
}
};
class European: virtual public Human
{
/* Uses inherited toEat() method instead of implementing by itself */
};
А що нам робити, якщо загальному коду необхідно викликати спеціалізовану функцію нащадка? - Ми просто викликаємо віртуальну функцію, а її кожен нащадок реалізує самостійно.
А чим ці функції відрізняються від звичайних?
#include <iostream>
using namespace std;
class Parent
{
public:
void hello()
{
cout<<"Hello!"<<endl;
}
};
class Child: public Parent
{
public:
void hello()
{
cout<<"Hi!"<<endl;
}
};
int main()
{
Child bob;
Parent John;
bob.hello();//Hi!
John.hello();//Hello!
system("pause>nul");
}
class Child реалізую функцію hello() по своєму. В чому різниця?
Є речі які особисто мені тяжко перекласти на українську, але якщо ти більше менш занєш англійську то можеш глянути тут.
http://msdn.microsoft.com/uk-ua/library/0y01k918.aspx
Ось приклад з цієї статті.
// deriv_VirtualFunctions2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Base {
public:
virtual void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Derived::NameOf() {
cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
cout << "Invoked by Derived\n";
}
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
}
Результат
Derived::NameOf
Invoked by Base
Derived::NameOf
Invoked by Derived
class Child реалізую функцію hello() по своєму. В чому різниця?
Спробуйте тепер у класі Parent створити метод test, що викликає hello. Потім створіть об'єкт класу Child та викличте test. В залежності від того, є hello віртуальним чи ні, ви отримаєте або "Hello!" або "Hi!".
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися