C++;虚拟值之间的差值=0;和空函数 我现在学习C++,面向对象,我总是看到这个: class SomeClass{ virtual void aMethod()=0; } class AnotherClass{ void anotherMethod(){/*Empty*/} } class SomeClassSon : public SomeClass{ void aMethod(){/*Also Empty*/} }

C++;虚拟值之间的差值=0;和空函数 我现在学习C++,面向对象,我总是看到这个: class SomeClass{ virtual void aMethod()=0; } class AnotherClass{ void anotherMethod(){/*Empty*/} } class SomeClassSon : public SomeClass{ void aMethod(){/*Also Empty*/} },c++,oop,class,methods,C++,Oop,Class,Methods,这三种方法的区别是什么?虚拟值等于零,为空,而虚拟值由于是继承的,因此为空 为什么我不能让SomeClassSon方法像父方法一样,虚空等于零?区别在于虚空aMethod()=0是a,意思是: SomeClass成为抽象基类, 这意味着它不能被实例化 从SomeClass继承的任何类都必须实现aMethod,否则它也将成为无法实例化的抽象基类 请注意,任何具有一个或多个纯虚函数的类都自动成为抽象基类。纯虚使类抽象。空的非虚拟方法没有任何作用-如果您试图调用它,它只会导致链接器错误。相反,您不能尝

这三种方法的区别是什么?虚拟值等于零,为空,而虚拟值由于是继承的,因此为空


为什么我不能让SomeClassSon方法像父方法一样,虚空等于零?

区别在于
虚空aMethod()=0
是a,意思是:

  • SomeClass
    成为抽象基类, 这意味着它不能被实例化
  • SomeClass
    继承的任何类都必须实现
    aMethod
    ,否则它也将成为无法实例化的抽象基类

  • 请注意,任何具有一个或多个纯虚函数的类都自动成为抽象基类。

    纯虚使类抽象。空的非虚拟方法没有任何作用-如果您试图调用它,它只会导致链接器错误。相反,您不能尝试调用纯的
    虚拟的
    (除非您尝试从构造函数调用它,这是很糟糕的),因为编译器不允许您创建该对象

    还有一个逻辑上的区别-标记为
    virtual
    的方法通过继承链是虚拟的-其他方法只是常规方法。

    纯虚拟函数(您的第一个示例,
    =0
    )意味着必须在派生类中重写该函数才能实例化该类的对象

    第二个基本上只是一个不做任何事情的成员函数。由于函数具有不同的名称,并且类与
    SomeClass
    无关,因此这两个类根本不会相互影响

    第三个重写纯虚函数,因此可以实例化
    SomeClassSon
    ,但在派生类中被重写的函数不起任何作用。

    声明aMethod()=0告诉编译器必须在子类中提供此方法。任何未实现该方法的子类都无法实例化。这有助于确保基类的任何对象都将实现该方法。

    您所指的“等于0”称为“纯虚拟”。这是一个需要实例化的子类必须实现的函数,而不是提供基本功能,这意味着父类将定义必须存在的功能,但父类不知道子类将如何实现。注意,这使得类变得抽象,因为它不能被实例化。例如,我可能想定义一个我可以继承的“哺乳动物”类,我希望它的子类以某种方式行事——但我不能简单地制造一个“哺乳动物”。相反,我会创建一个“Giraffe”类,并确保它的行为符合预期

    这个问题也解释了

    您所指的“Empty”函数是定义了函数并可以调用的功能,但它什么也不做。

    对于您的

    class SomeClass{
       virtual void aMethod()=0;
    }
    
    纯虚方法的存在使类变得抽象。一旦类中有一个这样的纯虚拟方法,
    =0
    ,就不能实例化该类。此外,任何派生类都必须实现纯虚拟的
    aMethod()
    ,否则它也将成为抽象类

    在派生类中,覆盖上面的纯虚方法,这使派生类成为非抽象类。您可以实例化这个派生类

    但是,在派生类中,方法的主体是空的,对吗?这就是为什么你的问题是有意义的:为什么不让这个类也成为纯虚拟的呢。嗯,你的课可能需要其他方法。如果是这样的话,
    SomeClass
    不能实例化(有一个纯虚拟方法),而子类
    SomeClassSon
    可以实例化


    这同样适用于您的
    另一个类
    ,它可以被实例化,与
    SomeClass

    SomeClass相反;s、 aMethod()
    不是有效的调用。区别在于,基类中的
    =0
    ,每个派生类都必须实现该方法。@DavidSchwartz-如果该类被实例化,则必须实现该函数。如果函数没有实现,则类是抽象的。也许你的意思是对的,但说错了:从
    SomeClass
    派生的类不会被强制实现函数,但如果它们没有实现,那么它们也是抽象的。