6

I have an existing class that declares a virtual method and defines a default implementation. Now I want to overload that method with a differend parameter and also give a default implementation. Additionaly I want to enforce the constraint, that if the first method got overridden by a subclass then the second (overloaded) virtual method must be overridden too.

Is this even possible inside C++? If so, is it possible at compile time?

Example code:

class ParamA {};
class ParamB {};

class Base
{
public:
    virtual void method(ParamA a)
    {
        // default behavior
    }
    virtual void method(ParamB b)
    {
        // default behavior
    }
}

class Derived : public Base
{
public:
    virutal void method(ParamA)
    {
        // special behavior
    }
}

My goal is to detect classes of type Derived and enforce them to implement their verison of method(ParamB b).

js_
  • 63
  • 3
  • 1
    You could make both virtuals in the base class pure virtual... – Fred Foo Jan 13 '12 at 13:33
  • Sadly that's not an option... – js_ Jan 13 '12 at 13:35
  • 1
    @js_: Why isn't it an option? It's about the only way of (almost) enforcing the rules you want. – Mike Seymour Jan 13 '12 at 13:41
  • The goal perserve legacy behavior, especially when users of `Base` didn't override `method(Param A)`. When making both methods pure virtual there would be a lot of code to go through and add trivial overrides. – js_ Jan 13 '12 at 13:53
  • Related: [How to obtain a pointer out of a C++ vtable?](http://stackoverflow.com/q/5099967/196844) and [Access v-table at run-time](http://stackoverflow.com/q/5740155/196844) – Daniel Trebbien Jan 13 '12 at 15:34

4 Answers4

5

No, you can't specify complex constraints on which sets of member functions must be overridden. The only constraints apply to individual functions; pure virtual (=0) to mandate overriding, and (in C++11) final to prevent overriding.

The best you can do is make both functions pure virtual, forcing the derived class to override both. This at least forces the author of the derived class to think about what needs overriding; it's impossible to override one and forget the other one.

You can still provide a default implementation, so that derived classes that don't want to override either function only need very short overrides that call the default versions.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

I think C++ does not provide any means to detect such missing override in a child.

@larsmans: Making both methods pure virtuals leads to missing the default implementation.

@js_: could you elaborate a bit on your actual issue? What you are searching for seems to be conceptually not that clear to me.

boto
  • 455
  • 2
  • 13
  • The `@` syntax only works in comments, not in answers. Answers are intended to answer the question *only*, not provide commentary or ask questions. – Cody Gray - on strike Jan 13 '12 at 13:42
  • You can provide an default implementation of a pure virtual function. Derived classes must override it, but they're free to call the default version if that's the desired behaviour. – Mike Seymour Jan 13 '12 at 13:43
  • Cody Gray: My answer (at least one part of the answer) was that C++ does not provide such mechanism. Mike: pure virtuals have no body, or am I missing something you mentioned!? – boto Jan 13 '12 at 13:45
  • 2
    @boto: You are missing something - pure virtuals *can* have a body. They just have to be overridden, so the default version can only be called statically. [Here's an example](http://ideone.com/bHQlu). – Mike Seymour Jan 13 '12 at 13:51
  • @boto: The long time goal is to get rid of the method currently in use (the one with `ParamA`) and replace it with the new method using the new parameter (since `ParamB` is a generalization of `ParamA`). But for now both parameters should be valid, especially when you wand default/legacy behavior. – js_ Jan 13 '12 at 14:06
  • @js_: I would suggest you to choose a different name than "method" for the newer method in order to avoid any silent errors or confusions in your code. It would not be always obvious in first glance which method the compiler will take on a call as the old method signature is even compatible with the new one (..."since ParamB is a generalization of ParamA") -- certainly, the compiler will take the best fitting signature, but this may not be always obvious to you as programmer. – boto Jan 13 '12 at 14:17
0

How about creating a Parent class from which Base will inherit? These 2 functions will be pure virtual in the Parent class. The derived classes will inherit Parent (and not Base), and will have to implement both functions.

Igor
  • 26,650
  • 27
  • 89
  • 114
0

If you all you have to work with is the parent class, then no. It's not possible neither at compile time, nor as a runtime check.

Of course, you could introduce some macros (like say OVERRIDE_METHODS... I'm sure you see what I'm talking about), but nothing can prevent the users from ignoring them and override only one of said methods.

Plus such macros will make the code pretty ugly.

stanson
  • 61
  • 6