为什么我们需要C ++中的虚函数?

我正在学习C ++,而我正在进入虚拟功能。

从我读过的(书中和在线中),虚函数是基类中的函数,您可以在派生类中重写。

但在本书的前面,在学习基本继承时,我能够在不使用virtual情况下重写派生类中的基本函数。

那么我在这里错过了什么? 我知道虚拟功能还有更多,它似乎很重要,所以我想清楚它究竟是什么。 我在网上找不到直接的答案。


以下是我如何理解不仅是什么virtual功能,而且为什么它们是必需的:

假设你有这两个类:

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."; }
};

在你的主要功能:

Animal *animal = new Animal;
Cat *cat = new Cat;

animal->eat(); // Outputs: "I'm eating generic food."
cat->eat();    // Outputs: "I'm eating a rat."

到目前为止很好,对吧? 动物吃普通食物,猫吃老鼠,全都没有virtual

现在让我们稍微改变它,以便通过中间函数调用eat() (这个例子只是一个简单的函数):

// This can go at the top of the main.cpp file
void func(Animal *xyz) { xyz->eat(); }

现在我们的主要功能是:

Animal *animal = new Animal;
Cat *cat = new Cat;

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating generic food."

呃哦...我们把一只猫传给func() ,但它不会吃老鼠。 如果你重载func()所以它需要一个Cat* ? 如果你必须从动物中获得更多的动物,他们都需要自己的func()

解决的办法是让Animal类的eat()成为一个虚函数:

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."; }
};

主要:

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating a rat."

完成。


没有“虚拟”,你会得到“早期绑定”。 根据您调用的指针类型,在编译时决定使用哪种方法。

用“虚拟”你会得到“后期绑定”。 基于指向对象的类型 - 运行时决定使用哪个方法的实现 - 它最初的构造方式是什么。 这不一定基于指向该对象的指针的类型。

class Base
{
  public:
            void Method1 ()  {  std::cout << "Base::Method1" << std::endl;  }
    virtual void Method2 ()  {  std::cout << "Base::Method2" << std::endl;  }
};

class Derived : public Base
{
  public:
    void Method1 ()  {  std::cout << "Derived::Method1" << std::endl;  }
    void Method2 ()  {  std::cout << "Derived::Method2" << std::endl;  }
};

Base* obj = new Derived ();
  //  Note - constructed as Derived, but pointer stored as Base*

obj->Method1 ();  //  Prints "Base::Method1"
obj->Method2 ();  //  Prints "Derived::Method2"

编辑 - 看到这个问题。

另外 - 本教程将介绍C ++中的早期和晚期绑定。


您至少需要1级继承和downcast来展示它。 这是一个非常简单的例子:

class Animal
{        
    public: 
      // turn the following virtual modifier on/off to see what happens
      //virtual   
      std::string Says() { return "?"; }  
};

class Dog: public Animal
{
    public: std::string Says() { return "Woof"; }
};

void test()
{
    Dog* d = new Dog();
    Animal* a = d;       // refer to Dog instance with Animal pointer

    cout << d->Says();   // always Woof
    cout << a->Says();   // Woof or ?, depends on virtual
}
链接地址: http://www.djcxy.com/p/14099.html

上一篇: Why do we need virtual functions in C++?

下一篇: how to dynamically increase the stack size of a process