C++中的虚拟关键字使用

Virtual keyword use in C++

本文关键字:关键字 虚拟 C++      更新时间:2023-10-16

我知道C++通过虚拟函数实现了运行时多态性,并且虚拟关键字是继承的,但我看不到在派生类中使用虚拟关键字。

例如,在下面的情况下,即使您在派生类中删除了虚拟关键字,ptr->method()调用仍然会转到派生::method。那么这个虚拟关键字在派生类中还有什么作用呢?

#include<iostream>
using namespace std;
class base
{
public:
    virtual void method()
    {
        std::cout << std::endl << "BASE" << std::endl;
    }
};
class derived: public base
{
public:
    virtual void method()
    {
        std::cout << std::endl << "DERIVED" << std::endl;
    }
};
int main()
{
    base* ptr = new derived();
    ptr->method();
    return 9;
}

如果派生类的方法通过名称和签名与其中一个基类的虚拟方法匹配,并且匹配的方法是虚拟的,则派生类的该方法也将变为虚拟的。因此,从技术上讲,没有必要在派生类中将此类方法标记为"virtual"。然而,在C++11之前,它曾经是一种很好的实践,因为它对阅读代码的人来说是一个很好的提示(很难记住基类的所有虚拟函数)。

从C++11开始,在派生类中有两个额外的关键字用于实现这一点,这有助于可读性和代码健壮性。它们是"超控"answers"最终"。例如,在派生类的方法中放入«override»可以确保基类的相应方法实际上是虚拟的。«final»关键字也起到了同样的作用,而且它可以防止该方法被进一步重写。

我还在博客中写了更多真实世界的理由和代码示例。

希望能有所帮助。祝你好运

什么都没有。只是为了提醒您哪些功能是虚拟的或非虚拟的。

virtual仅在基类声明中是必需的。它在派生类中是可选的,在这些情况下可能主要用作提醒。

C++11引入override使事情变得更加明确:它明确地将派生类中的方法标记为基类的virtual方法的重写。

派生类中的隐式虚拟方法在派生类中是虚拟的,无需显式定义它们为虚拟的。如果你声明,那将是多余的声明。

ptr->method();

当编译器发现上面的语句时

->它将尝试解析上述语句,因为method()函数是虚拟的,编译器将该调用的解析推迟到运行时。

->当您在运行时创建派生类的对象时,现在编译器将知道此方法是派生类的。

这个虚拟关键字在派生类中还有什么作用

考虑这个场景,在派生形式中还有一个派生类Derived2,它有自己的虚拟方法。

 class derived2: public derived
{
public:
    virtual void method()
    {
        std::cout << std::endl << "DERIVED2" << std::endl;
    }
};

如果你像下面的一样在main中调用方法()

int main()
{
    base* ptr = new derived2();
    ptr->method();   //derived2 class method() will get called
    return 9;
}

如果derived2中的method()默认情况下不是虚拟的,那么您最终将调用method(()的派生版本,从而失去运行时多态性的好处。

因此,c++的作者在这里做得很好,他们使虚拟关键字继承具有层次性。

virtual关键字在drive类中是可选的,因为根据规则,当您用具有虚拟函数的基类驱动类时,以及当您在drive类编译器中重写虚拟函数时,会在函数的同时隐式分配virtual关键字。因此,您不需要显式地分配虚拟关键字。但是这个关键字在多级继承过程中是必需的。

示例:

在您的代码中,我们添加了此代码。

   class derived: public base {
    public:
        virtual void method() {    // In this line virtual keyword is optional.
              std::cout << std::endl << "DERIVED :: method function" << std::endl;
        }
        virtual void display() {
              std::cout << std::endl << "DERIVED :: display function" << std::endl;
        }
   };
   class deriveChild: public derived {
        public:
            void method() {
                 std::cout << std::endl << "DERIVECHILD :: method" << std::endl;
            }
        void display() {
                 std::cout << std::endl << "DERIVECHILD:: display" << std::endl;
            }
   };

在main()中,如果您使用以下代码,它将为您提供不同的输出。

   base  *ptr = new deriveChild();
   ptr->method(); // will compile and execute
   ptr->display(); // will generate error because display() is not part of base class.

现在,如果您想使用deriveChild类的display(),请使用以下代码。

   derived *ptr = new deriveChild();
   ptr->method(); // Compile and Execute 
   ptr->display(); // Compile and Execute