1

Тема: Для чого створювати віртуальні функції?*

не можу зрозуміти навіщо створювати віртуальні функції. Наскільки я зрозумів якщо існує вказіник обєкт класа який наслідує базовия клас в якому є віртуальні методи то вони не будуть презапсані?

2

Re: Для чого створювати віртуальні функції?*

Почитайте про поліморфізм. Дуже складно пояснити, що це у кількох словах.

3

Re: Для чого створювати віртуальні функції?*

Віртуальність дозволяє здійснювати перевантаження методів класу зі збереженням принципу ієрархії класів. Базовий клас - це деякий "спільний набір рис" для різних типів даних, тому, наприклад, і до європейця, і до американця можна звернутися "людино!". Однак кожен з них по-різному харчується. У цьому разі метод 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);
    }
}

Тож за цим кодом американець має власний алгоритм споживання, тоді як "класичний європеєць" задовольняється і "природним способом харчування". Тому, якщо до американця звернутися "гей ти, людино, дуй на палубу!", то його спосіб харчування, очевидно, буде "природним". А якщо "пане американцю, прошу на палубу!", то тоді харчування буде за "суто американським" способом, тож віртуально він харчується та'як звичайні люди, а реально - по-американськи.

I belong to the Dead Generation.

4

Re: Для чого створювати віртуальні функції?*

Будь ласка напишіть простенький код з використання віртуальних функцій.

5

Re: Для чого створювати віртуальні функції?*

Приклад із реального життя: в програмах, що займаються обліком товарів на складі часто використовуються файли у форматі MMO та (його нащадку) XMMO. Ці формати мають багато чого спільного, але є і відмінності. Ми не хочемо копіпастити код, що реалізує спільний функціонал у два різних класи (бо це буде жах з точки зору підтримки), а хочемо щоб він увесь був в одному місці. У цьому випадку один із найкращих варіантів - це наслідування. Ми пхаємо загальний код у клас предок, а усі відмінності реалізовуємо у нащадках. А що нам робити, якщо загальному коду необхідно викликати спеціалізовану функцію нащадка? - Ми просто викликаємо віртуальну функцію, а її кожен нащадок реалізує самостійно.

6

Re: Для чого створювати віртуальні функції?*

bodya-0028 написав:

Будь ласка напишіть простенький код з використання віртуальних функцій.


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 */
};
I belong to the Dead Generation.

7 Востаннє редагувалося bodya-0028 (03.02.2013 14:52:23)

Re: Для чого створювати віртуальні функції?*

Torbins написав:

А що нам робити, якщо загальному коду необхідно викликати спеціалізовану функцію нащадка? - Ми просто викликаємо віртуальну функцію, а її кожен нащадок реалізує самостійно.

А чим ці функції відрізняються від звичайних?

#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() по своєму. В чому різниця?

8

Re: Для чого створювати віртуальні функції?*

Є речі які особисто мені тяжко перекласти на українську, але якщо ти більше менш занєш англійську то можеш глянути тут.
http://msdn.microsoft.com/en-us/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
Подякували: bodya-00281

9

Re: Для чого створювати віртуальні функції?*

bodya-0028 написав:

class Child реалізую функцію hello() по своєму. В чому різниця?

Спробуйте тепер у класі Parent створити метод test, що викликає hello. Потім створіть об'єкт класу Child та викличте test. В залежності від того, є hello віртуальним чи ні, ви отримаєте або "Hello!" або "Hi!".

Подякували: bodya-00281