【问题标题】:abstract class and virtual functions抽象类和虚函数
【发布时间】:2020-07-01 23:50:52
【问题描述】:

这个类会被认为是一个抽象类,因为它有一个虚函数吗?我仍然能够创建一个 Animal 对象并调用 getFoodCost();

我认为抽象类不能被实例化。这是否意味着对象可以具有虚函数而不被视为抽象类?

class Animal
{
public:
    Animal();
    int getBabies();
    double getFoodCost();
    virtual double getPayOff();
    int getQty();

    void incAge();
    void setAge(int);

protected:
    int counter=0;
    int age;
    int cost;   
};

【问题讨论】:

    标签: c++ abstract-class


    【解决方案1】:

    这个类会被认为是一个抽象类,因为它有一个虚函数吗?我仍然能够创建一个 Animal 对象并调用 getFoodCost();

    没有。在 C++ 中,“抽象类”通常是指带有pure virtual function 的类:

    class Abstract {
    public:
        virtual void PureVirtual() = 0; // no implementation
    };
    
    class NotAbstract {
        virtual void NotPureVirutal() {
            // Some implementation
        }
    };
    

    我认为抽象类不能被实例化。

    是的,没错。这是因为抽象类具有不需要实现的功能。它无法直接实例化实例。它使用继承和指针/引用来引用抽象类。

    这是否意味着对象可以具有虚函数而不被视为抽象类?

    是的。同样,抽象类是具有纯虚函数的类。这与常规的虚函数不同。如上所述,纯虚函数没有必需的实现。另一方面,常规虚函数需要有一个与之关联的实现,因此它们可以被实例化。

    【讨论】:

    • 我知道这有点奇怪,但是纯虚函数可以在 C++ 中实现。它们只是不需要并且在大多数情况下是无用的。在纯虚析构函数的情况下,纯虚函数甚至必须实现。
    • 所以说“没有有用的实现”也许更好?
    • 我会选择“不需要实现”,因为使虚拟成员函数成为纯虚拟的关键是您不想为其提供实现,或者您想明确地制作类抽象,因此无法创建实例。需要实现一个非纯 virtual 函数。
    • @walnut 来自 C++20 标准:“纯虚函数仅在使用或如同使用qualified-id 语法调用时才需要定义”。 “as if with”部分涵盖了析构函数。因此,当可以直接调用纯虚函数时,需要定义它们,例如在 NotAbstract 成员函数中使用 Abstract::PureVirtual()。
    • @leon 我认为它被称为“虚拟课堂”,但我无法在某个地方找到它来确认。我特别犹豫要不要这么称呼它,因为该名称可能与所谓的“虚拟继承”相关联,这完全是另一回事。或者,您对“具有虚函数的普通类”的建议可能会起作用:D
    【解决方案2】:

    抽象函数是 virtual 成员函数,您可以为它执行 = 0,如

    virtual double getPayOff() = 0;
    

    具有至少一个抽象函数(包括继承的函数)的类是抽象类。具有only纯虚函数的类是所谓的纯抽象类(也称为interface类)。

    由于您的 getPayOff 函数不是纯虚拟的,因此您的类也不是抽象的。

    【讨论】:

    • 标准是否真的定义了“纯抽象类”这个术语?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 2020-06-19
    • 2019-04-08
    • 2023-03-14
    • 1970-01-01
    • 2013-01-15
    • 2019-04-20
    相关资源
    最近更新 更多