为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++ C
慕妹3146593 2019-06-01 16:30:52
为什么我们需要C+中的虚拟函数?我正在学习C+,我只是进入了虚拟函数。根据我在书中和网上所读到的,虚拟函数是基类中的函数,您可以在派生类中重写这些函数。但是在这本书的早些时候,当我学习基本继承时,我可以在派生类中重写基函数,而不需要使用virtual.我在这里错过了什么?我知道虚拟函数还有更多,而且它似乎很重要,所以我想弄清楚它到底是什么。我只是在网上找不到一个直截了当的答案。
查看完整描述

3 回答

?
红颜莎娜

TA贡献1842条经验 获得超12个赞

这是我所理解的,而不仅仅是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 filevoid 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().

解决办法是eat()Animal对虚拟函数进行分类:

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

完成了。


查看完整回答
反对 回复 2019-06-01
?
慕森卡

TA贡献1806条经验 获得超8个赞

如果没有“虚拟”,您就会得到“早期绑定”。在编译时将根据调用的指针的类型来决定方法的实现。

与“虚拟”你得到“晚绑定”。在运行时,将根据指向对象的类型来决定该方法的实现,该对象最初是作为什么构造的。根据指向该对象的指针的类型,这不一定是您所想的。

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+绑定。



查看完整回答
反对 回复 2019-06-01
  • 3 回答
  • 0 关注
  • 610 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信