我在基类中有一个函数 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
的存在实际上决定了基方法(首先在类中定义新的虚拟方法(和重写方法之间的区别。它由编译器静态检查。