1

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.

Franken Steak
  • 60
  • 2
  • 9
  • Hmmm, i see. So basically, I'd make it a virtual function if i want the derived class to over-ride the base class function. Thank-you very much =) – Franken Steak Oct 19 '13 at 14:11
  • I've seen a number of `reset` implementations by now, and it is generally a maintenance burden more than anything else. If you do not need an object any longer, throw it away. If you need a new object, build a new one. – Matthieu M. Oct 19 '13 at 15:12
  • @MatthieuM. Honestly, i would prefer to not have a reset() function as it is truly a burden. But, unfortunately, the program is being marked by another program that checks for a reset() function instead of if the program does what it's supposed to. – Franken Steak Oct 19 '13 at 16:53

3 Answers3

2

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
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • The destructor of the base class should be *either* `virtual` *OR* `protected`, depending on whether one is supposed to call `delete` on a pointer-to-base or not. Also, the copy-constructor and copy-assignmnent operator should be `protected` to help prevent unintentional slicing. – Matthieu M. Oct 19 '13 at 15:10
1

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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

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.

Community
  • 1
  • 1
Jason Enochs
  • 1,436
  • 1
  • 13
  • 20