-->

When my base class and derived have the same funct

2019-07-22 08:29发布

问题:

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?

Eg.

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();
};

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

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

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

Any and help is appreciated, thank-you.

回答1:

Is this code right?

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);

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

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

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;

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

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


回答2:

It depends on your intention. You may have this function either as virtual or as non-virtual. Consider for example the folloing function

void f( Base &b )
{
    b.reset();
}

int main()
{
    Derive d1;
    f( d1 );
    Derive_two d2;
    f( d2 );
}

So the question is whether you want that function f would reset only the data member of the base subobject or it should reset data members of the object passed to it by reference.



回答3:

This similar StackOverload question explains virtual methods and provides a great example:

Why do we need Virtual Functions in C++?

Let me know if that doesn't answer your question.