关于OOP:C++virtual = 0; 与 empty

C++ difference between virtual = 0; and empty function

我现在正在学习C++,面向对象,我一直都是这样:

1
2
3
4
5
6
7
8
9
10
11
class SomeClass{
   virtual void aMethod()=0;
}

class AnotherClass{
   void anotherMethod(){/*Empty*/}
}

class SomeClassSon : public SomeClass{
   void aMethod(){/*Also Empty*/}
}

我的疑问是:这三种方法有什么不同。虚拟等于零,空的,由于它是继承的,所以虚拟等于空的。

为什么我不能像父亲那样做一个SomeClassson方法呢?(虚空等于零?)


为了你

1
2
3
class SomeClass{
   virtual void aMethod()=0;
}

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

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

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

这同样适用于您的AnotherClass,它可以被实例化,与SomeClass相反。


区别在于virtual void aMethod() = 0是一个纯虚拟函数,意思是:

  • SomeClass成为抽象基类,这意味着它不能被实例化。
  • 继承SomeClass的任何类必须实现aMethod,否则它也将成为无法实例化的抽象基类。
  • 请注意,任何具有一个或多个纯虚拟函数的类都自动是抽象基类。


    您所指的"等于0"称为"纯虚拟"。这是一个要实例化的子类必须实现的函数,而不是提供基本功能,这意味着父类将定义必须存在的功能,但父类不知道子类将如何实现它。注意,这使得类抽象化,因为它不能被实例化。例如,我可能想定义一个我可以继承的"哺乳动物"类,我想让它的孩子以某种方式行动——但我不能简单地定义一个"哺乳动物"。相反,我会创建一个"长颈鹿"类,并确保它的行为是应该的。

    在这个问题上也有解释。

    您所指的"空"函数是指定义了函数并可以调用的函数,但它什么也不做。


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


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

    第二个基本上只是一个不做任何事情的成员函数。由于函数的名称不同,类与SomeClass没有关系,所以两者根本没有相互影响。

    第三个重写纯虚函数,因此可以实例化SomeClassSon,但在派生类中,重写函数什么也不做。


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

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