14

我现在正在学习 C++,OO 方面,我一直看到这个:

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

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

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

3种方法有什么区别?虚拟等于 0,空的等于 1,而虚拟的,因为它是继承的,所以是空的。

为什么我不能像父亲一样让 SomeClassSon 方法,virtual void 等于 0?

4

6 回答 6

17

为您

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

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

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

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

同样适用于您的AnotherClass,它可以被实例化,与SomeClass.

于 2013-02-25T20:18:46.923 回答
7

不同之处在于它virtual void aMethod() = 0是一个虚函数,这意味着:

  1. SomeClass成为一个抽象基类,这意味着它不能被实例化。
  2. 任何继承自的类都SomeClass必须实现aMethod,否则它也成为无法实例化的抽象基类

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

于 2013-02-25T20:15:00.120 回答
4

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

在这个SO question 中也对此进行了解释。

您所指的“空”函数是定义函数并且可以调用的功能 - 但什么也不做。

于 2013-02-25T20:17:44.247 回答
3

声明 aMethod()=0 告诉编译器必须在子类中提供此方法。任何没有实现该方法的子类都不能被实例化。这可以帮助您确保基类的任何对象都将实现该方法。

于 2013-02-25T20:16:16.740 回答
2

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

第二个基本上只是一个什么都不做的成员函数。由于函数名称不同且类与 无关SomeClass,因此两者根本不会相互影响。

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

于 2013-02-25T20:15:19.197 回答
1

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

还有一个逻辑差异 - 标记的方法virtual将通过继承链是虚拟的 - 其他只是常规方法。

于 2013-02-25T20:15:08.207 回答