虚函数和抽象类

时间:2011-04-16 19:09:14

标签: c++ visual-c++

我在书中读到:

抽象类是一个专门用作基类的类。抽象类包含至少一个纯虚函数。您可以在类声明中的虚拟成员函数声明中使用纯说明符(= 0)声明纯虚函数。

抽象类是否必须具有虚函数?为什么呢?

纯虚函数和虚函数有什么区别?它们的需求是什么?

10 个答案:

答案 0 :(得分:7)

纯虚函数指定一个接口,必须在派生类中重写,才能创建派生类的对象。

(非纯)虚函数指定可以在派生类中重写的接口,但基类提供接口的默认实现。

对于大多数实际用途,是的,抽象基类必须至少包含一个虚函数。抽象基类的重点是指定由派生类实现的接口。该接口是根据可以调用的许多虚函数指定的。没有虚函数,你没有指定一个接口,这使得抽象基类很难完成很多工作。

答案 1 :(得分:2)

如果使用抽象类,则意味着您不希望错误地实例化此类。并且你必须在该类中使用纯虚函数。但是在类中声明或编写函数是你的选择。您也可以在派生类中编写函数。

答案 2 :(得分:1)

不同之处在于无法实例化抽象类 - 它充当interface

答案 3 :(得分:1)

要成为抽象类,必须有一个纯虚函数。只有虚函数可以是纯函数,因为它可以被覆盖,因此它对多态有用。纯粹的非虚函数没有意义,因为它没有做任何事情而且无法覆盖,所以它没用,并且不存在:)

答案 4 :(得分:1)

是的,它必须至少有一个纯虚拟功能。

如果你的基类的所有虚函数都有一个实现,并且你想让它抽象,你可以使用纯虚析构函数

class MyAbstractClass
{
    virtual ~MyAbstractClass() = 0;

    virtual void f() 
    {
        IHaveAnImplementation(); 
        SoICannotBePure();
    }
};

// The destructor can unfortunately not be defined inline
MyAbstractClass::~MyAbstractClass() {}

这只是一个方便:纯粹的析构函数不是真正的纯函数,因为它有一个定义。只有标记表示该类无法实例化,尽管它没有其他抽象函数。

答案 5 :(得分:0)

  

抽象类是否必须具有虚函数?为什么呢?

这取决于您使用的定义。标准使用

  

如果一个类至少有一个纯虚函数,那么它就是抽象的。

所以是的,它是强制性的。非正式地,您可以使用另一个定义,但是您可能会在C ++上下文中出现混淆。

  

纯虚函数和虚函数有什么区别?它们的需求是什么?

纯虚拟成员:

  • 必须在所有非抽象派生类

  • 中重写
  • 可以没有定义(但是可以给出一个定义,在纯虚析构函数的情况下甚至是强制性的。)

答案 6 :(得分:0)

纯虚拟意味着该方法没有实现,因此它强制任何非抽象子类提供该实现。

答案 7 :(得分:0)

在C ++中,使类抽象的唯一方法是在其中放置至少一个纯虚函数。编译器不允许您实例化包含纯虚函数的类,因为那时您将拥有一个没有定义的函数的对象。可能有一些神秘的方法来解决这个问题,但这是标准做法。

纯虚函数和虚函数之间的区别在于纯虚函数不指定方法的实现。 =0语法告诉编译器该类没有为函数提供定义,这使得函数纯虚拟并使类成为抽象。从抽象基类派生的任何类都必须定义纯虚函数,否则子类也将是抽象的。

“非纯”虚函数是用virtual关键字标记的函数,但函数的定义在基类中提供。这意味着基类提供了函数的实现,如果需要,任何子类都可以覆盖它。当您使用指向派生类对象的基类指针时,virtual关键字允许多态性工作。

答案 8 :(得分:0)

可以在派生类中重写虚函数。

必须在派生类中重写纯虚函数。

无法实例化具有纯虚函数的类。

答案 9 :(得分:0)

纯虚函数是必须由任何具体(即非抽象)派生类重写的函数。这在成员函数声明中使用语法" = 0"的声明中指出。

示例:

class AbstractClass {
public:
  virtual void AbstractMemberFunction() = 0; // Pure virtual function makes
                                             // this class Abstract class.
  virtual void NonAbstractMemberFunction1(); // Virtual function.

  void NonAbstractMemberFunction2();
};

通常,抽象类用于定义实现,并且旨在从具体类继承。它是强制类设计者和该类用户之间签订合同的一种方式。如果我们希望从抽象类创建一个具体的类(一个可以实例化的类),我们必须为基类的每个抽象成员函数声明和定义一个匹配的成员函数。否则,如果基类的任何成员函数未定义,我们将创建一个新的抽象类(这有时可能很有用)。