视觉 C++当我们在基类中使函数成为纯虚拟时,那么在子类中再次使相同的函数虚拟的必要性是什么

visual In C++ when we make a function pure virtual in base class then what is the necessity of making the same function virtual again in child class

本文关键字:函数 虚拟 子类 C++ 是什么 必要性 我们 基类 视觉      更新时间:2023-10-16

我在基类中有一个函数 X(( 声明为 PURE VIRTUAL:

class Base 
{
public:  
    virtual HRESULT X()=0; // Now it's pure virtual. 
    .......
    };


class Derived_1 : public Base  
  {   
    HRESULT X()   
    {  
    // body of function X() ; full definition given here as per Derived_1's context. SHOULD WE MAKE THIS VIRTUAL?                                                     
    }
    ..................              
  };            
class Derived_2 :public Base             
   {          
    HRESULT X()            
         {             
        // body of function X() ; full definition given here Derived_2's context.  SHOULD WE MAKE THIS VIRTUAL?
        }              
         ..................           
   };

如果我们的目的是使用基类指针一般地调用函数 X((,那么调用 X(( 的定义Derived_1或Derived_2的决策,那么是否有必要使派生类中的 X(( 也成为虚拟的。

Base * bPtr;
bPtr = new Derived_1(); OR bPtr = new Derived_2(); (Dynamic decision)
bPtr->X()

我觉得没有必要将 virtual 关键字附加到派生类中的定义。我说的对吗?

提前谢谢。

如果派生类中函数的签名(参数和返回值的类型、const 和 virtual 等标识符(与基类中的签名相同,则派生类中的函数将自动为虚拟函数。无论是虚拟的还是纯虚拟的,都无关紧要。

因此,在您的示例中,没有必要为派生类添加 virtual。

C++对此有一条规则:一旦虚拟,永远是虚拟的。 无论您是否在派生类中说"虚拟",都不会改变X()将是虚拟的事实。 你可以说或不说; 无论如何,X()在派生类中都是虚拟的。

一旦函数在基类中声明为 virtual,就不需要在派生类中声明 virtual。有时人们会在派生类中声明 virtual,因为他们觉得它更清晰,但这不是必需的。

在基类中声明为 virtual 的函数在派生类中是虚拟的,只要它具有相同的原型并且未显式声明 virtual。

无需

向派生类函数添加虚拟值。

参考: C++03 10.3 虚函数 第3段

[注意:虚拟成员函数不必可见即可被覆盖,例如,

struct B {
    virtual void f();
};
struct D : B {
    void f(int);
};
struct D2 : D {
    void f();
};

classD 中的functionf(int)将虚拟functionf()隐藏在其基本classB; D::f(int)不是虚函数。然而,在classD2中声明的f()B::f()具有相同的名称和相同的参数列表,因此是一个覆盖函数B::f()的虚函数,即使B::f()classD2中不可见。]

从技术上讲,没有必要写virtual.

实际上,它记录了该函数是virtual的:这意味着在继承时,我不必一直检查基类以查看它是否是virtual函数。它还强调了通常的警告:即来自构造函数或析构函数的调用,后果自负。

在C++11中,有一个更好的替代文档"继承的虚拟性",override关键字。

class Base { public: virtual void method() = 0; };
class Derived: public Base { public: void method() override; };

override 关键字表示消息覆盖基类方法(此处的基是可传递的(。如果没有重写基类方法,则代码是错误的,编译器将产生错误。

因此,override的存在实际上决定了方法(首先在类中定义新的虚拟方法(和重写方法之间的区别。它由编译器静态检查。