1.11.2018

Pure virtual function in C++ (轉貼)


純虛擬函式、抽象類別(Abstract class)


C++預設函式成員都不是虛擬函式,如果要將某個函式成員宣告為虛擬函式,則要加上"virtual"關鍵字,然而C++提供一種語法定義「純虛擬函式」 (Pure virtual function),指明某個函式只是提供一個介面,要求繼承的子類別必須重新定義該函式,定義純虛擬函式除了使用關鍵字"virtual"之外,要在函 式定義之後緊跟著'='並加上一個0,例如:
class Some {
public:
    // 純虛擬函式
    virtual void someFunction() = 0;

    ....
};

一個類別中如果含有純虛擬函式,則該類別為一「抽象類別」(Abstract class),該類別只能被繼承,而不能用來直接生成實例,如果試圖使用一個抽象類別來生成實例,則會發生編譯錯誤。

Why do we need virtual functions in C++? (轉貼)

Why do we need virtual functions in C++?



1989

down voteaccepted
I'm a C++ newbie myself, but here is how I understood not just what virtual functions are, but why they're required:
Let's say you have these two classes:
class Animal
{
    public:
        void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};
In your main function:
Animal *animal = new Animal;
Cat *cat = new Cat;

animal->eat(); // Outputs: "I'm eating generic food."
cat->eat();    // Outputs: "I'm eating a rat."
So far so good, right? Animals eat generic food, cats eat rats, all without virtual.
Let's change it a little now so that eat() is called via an intermediate function (a trivial function just for this example):
// This can go at the top of the main.cpp file
void func(Animal *xyz) { xyz->eat(); }
Now our main function is:
Animal *animal = new Animal;
Cat *cat = new Cat;

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating generic food."
Uh oh... we passed a Cat into func(), but it won't eat rats. Should you overload func() so it takes a Cat*? If you have to derive more animals from Animal they would all need their own func().
The solution is to make eat() from the Animal class a virtual function:
class Animal
{
    public:
        virtual void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};
Main:
func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating a rat."
Done.