了解虚拟函数和纯虚拟函数
虚拟函数通过启用运行时多态性在面向对象编程中发挥着至关重要的作用。根据维基百科的定义,虚拟函数是允许动态分派的可重写方法或函数。这意味着要执行的具体函数是在运行时根据对象的类型确定的,而不是在编译时。
与非虚函数相反,当在派生类中重写虚函数时,在最派生类中定义的版本在整个类层次结构中使用。这确保了始终利用该函数的最具体实现。
纯虚函数,也称为纯虚方法,进一步发展了这一概念。它们是虚函数,如果派生类不是抽象类,则必须在该派生类中实现它们。因此,纯虚函数有效地要求派生类中存在特定行为。
抽象类是包含一个或多个纯虚函数的类。此类类不能直接实例化;相反,必须使用为所有纯虚函数提供实现的派生类。
为了说明虚函数和纯虚函数之间的差异,请考虑以下 C code:
Base.hpp:
struct Base { virtual ~Base() = default; virtual void foo() { std::cout << "Base::Foo" << std::endl; } };
推导d.hpp:
struct Derived : public Base { void foo() override { std::cout << "Derived::Foo" << std::endl; } };
main.cpp:
int main() { Base base; base.foo(); // Calls Base::Foo Derived derived; derived.foo(); // Calls Derived::Foo Base* derived_as_base = &derived; derived_as_base->foo(); // Calls Derived::Foo (due to dynamic dispatch) }
中这段代码中,Base 类包含一个虚函数 foo,它打印“Base::Foo”。 Derived 类重写此函数以打印“Derived::Foo”。当 Base 对象调用 foo 时,输出为“Base::Foo”。然而,当 Derived 对象(作为 Base 指针访问)调用 foo 时,由于动态调度,输出为“Derived::Foo”。
现在,让我们考虑一个纯虚拟函数:
PureBase.hpp:
struct PureBase { virtual ~PureBase() = default; virtual void foo() = 0; // Pure virtual function };
PureDerived.hpp:
struct PureDerived : public PureBase { void foo() override { std::cout << "PureDerived::Foo" << std::endl; } };
在此代码中, PureBase 类包含一个未在基类中定义的纯虚函数 foo。因此,PureBase 类是抽象的,因为它缺乏完整的实现。
PureMain.cpp:
int main() { // error: cannot declare variable 'pureBase' to be of abstract type 'PureBase' // PureBase pureBase; // pureBase.foo(); PureDerived pureDerived; pureDerived.foo(); // Calls PureDerived::Foo }
在此示例中,尝试实例化 PureBase对象直接导致编译器错误。但是,创建 PureDerived 对象是允许的,因为它提供了 foo 函数的实现。
总而言之,虚拟函数提供动态调度,并且可以在派生类中重写。另一方面,纯虚函数需要在派生类中实现并强制执行特定的行为。这些概念共同在面向对象编程中实现多态功能方面发挥着至关重要的作用。
以上是面向对象编程中的虚函数和纯虚函数有什么区别?的详细内容。更多信息请关注PHP中文网其他相关文章!