【问题标题】:Virtual difference syntax C++ [duplicate]虚拟差异语法C ++ [重复]
【发布时间】:2011-06-05 03:21:19
【问题描述】:

在 C++ 中,虚拟是这样使用的吗?两者有什么区别?

class Animal
{
public: 
    virtual void something();
    virtual void something() = 0; 
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    我可能对此很模糊,但我认为第一个说:你可以覆盖我,第二个说,你必须覆盖我。

    【讨论】:

    • 至少有一个virtual ... () = 0;的类称为抽象类。你不能创建抽象类的实例,否则编译器会报错。
    【解决方案2】:
    virtual void something() = 0; // says it is a pure virtual function
    virtual void something(); // is a virtual function
    

    而包含至少一个纯虚函数的类称为抽象基类。抽象基类和常规多态类的主要区别在于,因为在抽象基类中,至少它的一个成员缺少实现,所以我们不能创建它的实例(对象)。

    【讨论】:

      【解决方案3】:

      第一个声明函数是虚拟的:子类可以覆盖行为。但是,该函数仍然在基类中有一个实现。第二个是纯虚拟:它没有实现,必须被子类覆盖。它类似于 Java 和 C# 中的 abstract 关键字。它也使类抽象,所以它不能被实例化。

      【讨论】:

      • 一点澄清:纯虚拟仍然可能有实现(并且在纯虚拟析构函数的情况下必须有实现) - 但是不使用虚拟调度调用实现。当期望派生类调用在父类中实现的一些基本处理时,通常会使用这种方法。见stackoverflow.com/questions/1306778/…
      【解决方案4】:

      第二个“东西”必须由子类实现,任何包含“xxx() = 0”的类都不能直接实例化。它被称为“纯虚”函数,包含它们的类是“抽象的”。一个只包含纯虚的类是“纯抽象的”。

      【讨论】:

        【解决方案5】:

        第一个只是声明一个虚拟方法。如果您扩展类并覆盖该方法,则会调用子类的实现。

        第二个是纯虚方法。换句话说,您的类或任何扩展它的类都不会被实例化(抽象)而不首先为某事()提供定义。

        【讨论】:

          【解决方案6】:

          考虑:

          class Sloth : public Animal { void something() { ... } };
          
          Animal animal;
          Sloth sloth;
          

          在这里,我们尝试创建两个对象 - Animal 和 Sloth。但是,我们应该被允许创造动物吗?也许程序员创建 Animal 只是为了让它可以多态地引用派生类型,如下所示:

          std::vector<Animal*> zoo;
          zoo.push_back(new Sloth());
          zoo.push_back(new Sea_Eagle());
          

          然后他们可能期望p_animal-&gt;something() 做一些有用的事情。鉴于Animal 仅用于这种多态抽象,任何人将实际的“new Animal()”对象直接放入动物园(或在程序中的其他任何地方操作)都是错误的。

          假设有可能——如果程序员使用这个Animal 类创建一个实例并调用something() 函数会发生什么?也许什么都没有,或者它可能是一个错误条件并且永远不应该出现在好的代码中——而不是让 Animal 的 something() 函数打印错误消息或在运行时抛出异常。这很难看 - 运行时错误意味着当客户端尝试使用程序时程序失败了。

          C++ 支持“= 0”表示法,因此编译器知道要防止在编译时创建(基类)Animal 对象,因此您可以发布始终适用于用户。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-01-01
            • 2013-01-15
            • 2021-11-26
            • 2016-10-22
            • 2017-08-13
            • 2012-09-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多