当我的基类和派生类具有相同的功能时,它是否必须是虚拟的? [英] When my base class and derived have the same function, does it HAVE to be virtual?

查看:26
本文介绍了当我的基类和派生类具有相同的功能时,它是否必须是虚拟的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个项目,我正在处理一个非常有层次的项目.在它的基类中,有一个函数 reset() 在所有派生类中都被调用.我很困惑的是,由于派生类中的这个重置基本上只是重置它的私有变量,然后调用它的前面(更高)类的 reset() 函数,重置函数是否必须是虚拟的?

So i have a project I'm working on with quite a hierarchy. In the base class of this there is a function reset() that gets called throughout all the derived classes. All I'm confused about is that, since this reset in the derived class basically just resets it's private variables and then calls it's preceding (higher) class' reset() function does the reset function have to be virtual?

例如

class Base
{
private:
   int some;
public:
   void reset();
};

class Derive : public Base
{
private:
   int some1;
public:
   void reset();
};

class Derive_two : public Derive
{
private:
   int some2;
public:
   void reset();
};

所以基本上 Derive_two 类的重置函数将如下所示.

So basically the Derive_two class' reset function will then look as follows.

void Derive_two::reset()
{
   some2 = 10;
   Derive::reset();
}

这段代码对吗?还是函数 reset() 需要是 virtual 类型?

Is this code right? Or does function reset() need to be of type virtual?

感谢任何帮助,谢谢.

推荐答案

这段代码对吗?

可能不是.它不是多态;这意味着通过指针或对 Base 的引用调用函数只会调用在 Base 中声明的版本.所以如下:

Probably not. It's not polymorphic; meaning that calling the function via a pointer or reference to Base will only call the version declared in Base. So the following:

void DoStuffAndReset(Base & b) {
    DoStuff(b);
    b.reset();
}

Derive d;
DoStuffAndReset(d);

不会完全重置 d,只会重置它的基类部分,这几乎肯定不是您想要的行为.

will not fully reset d, only the base-class part of it, which is almost certainly not the behaviour you want.

或者函数 reset() 需要是 virtual 类型吗?

Or does function reset() need to be of type virtual?

如果你想覆盖它,并且通过一个指针或对基类的引用可以调用覆盖的版本,则需要它;这可能是您想要的行为.通过将 reset 设为虚拟,我的示例将完全重置对象,无论它是什么类型.

It needs to be if you want to override it, and have the overridden version callable via a pointer or reference to the base class; which is probably the behaviour you want. By making reset virtual, my example would fully reset the object, whatever type it is.

同样,您可能需要一个虚拟析构函数,以便可以通过指向基类的指针正确删除对象.事实上,以下看似无害的代码实际上具有未定义的行为:

Likewise, you probably want a virtual destructor, so that objects can be correctly deleted via a pointer to the base class. As it is, the following harmless-looking code actually has undefined behaviour:

Base * b = new Derive;
delete b;

可以通过在 Basepublic 部分添加析构函数来修复:

which can be fixed by adding a destructor to the public part of Base:

virtual ~Base() {}  // assuming it doesn't need to do anything

这篇关于当我的基类和派生类具有相同的功能时,它是否必须是虚拟的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆