Sign in to follow this  
badger82

Making a derived member function impossible to override?

Recommended Posts

Hi All, Does anyone have any idea on how to make a derived classes member function impossible to override? For example:
class A
{
    void Foo(){};
};

class B : public A
{
    void Foo(){}; // We want to make this fail on compile
};

B b;
b.Foo(); // Happily calls the function from class B

Thanks :)

Share this post


Link to post
Share on other sites
This is definitely not part of standard C++, but it does work in visual C++, so you might want to macro it up....


#ifdef _MSC_VER
# define MY_SEALED sealed
#else
# define MY_SEALED
#endif

class A
{
virtual void Foo() MY_SEALED {};
};

class B : public A
{
void Foo() {}; // fails to compile.
};



Share this post


Link to post
Share on other sites
Don't make it virtual. If it absolutely has to be virtual, make it private and have a public function call it.

This is one of the reasons why virtual functions should never be public, only protected: you can make a virtual function private and therefore prevent any overrides.

Share this post


Link to post
Share on other sites
Hey ToohrVyk, we aren't making it virtual as you can see from the pseudo code source I gave. Thats actually part of the problem, We *never* want this overidded.

RobTheBloke, thats great :) I'm suprised it's not a standard keyword in C++ to be honest. It's a nice way to protect your classes from abuse.

Share this post


Link to post
Share on other sites
Quote:
Original post by badger82
Hey ToohrVyk, we aren't making it virtual as you can see from the pseudo code source I gave. Thats actually part of the problem, We *never* want this overidded.


Ah. Since you were using the term overriding I assumed that you referred to virtual functions (non-virtual functions are overloaded, not overridden).

I am not aware of any means of preventing overloading of functions from the base class. However, I am not aware of any problems (or potential abuse) related to it either.

Share this post


Link to post
Share on other sites
Thanks ToohrVyk for correcting my mistake there. Essentially we have had instances where a derived class overloads the function from a base class and while this is perfectly legal in some instances it is really not desirable. If we have a way like "sealed" to tell both the compiler and anyone looking at the header that you shouldn't under any circumstances overload or override this function then it would just be handy ;)

Share this post


Link to post
Share on other sites
I think ToohrVyk was basically saying that declaring virtual funcs for the sake of it isn't a great idea, and i'm tempted to agree - which is certainly one of the problems of my original code snippet. I'd almost be tempted to do something like this, to prevent the virtuals getting defined in the release build, but still giving you the compile errors in debug. maybe.


#if defined(_MSC_VER) && defined(_DEBUG)
# define CANNOT virtual
# define BE_OVERRIDDEN sealed
#else
# define CANNOT
# define BE_OVERRIDDEN
#endif

class A
{
CANNOT void Foo() BE_OVERRIDDEN {};
}


Share this post


Link to post
Share on other sites
My solution:
// This class is not intended to be derived
...
// This function should not be overriden


Seems to be working fine for standard and many other libraries.

Other approach:
struct Foo {
void bar() { internal_bar(); }
private:
void internal_bar() {
x += 1;
}
int x;
};
People can override, but cannot replicate required behavior, causing the class to break. Then again:
*((int*)(((char *)(&foo))+22)) = 1;
or something along these lines...

Share this post


Link to post
Share on other sites
@Sneftel - Lol, that was an option that we had already considered. Personally I had never come across this problem before in all my time coding with C++. But I can see why someone relatively new to C++ may overload instead of override for example, we just want something to moan at them when they do ;)

@RobTheBloke - Yeah I completely agree with his comment on not declaring virtuals for the sake of it and think your solution is a nice way to go about it.



Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
My solution:
// This class is not intended to be derived
...
// This function should not be overriden


I used to think that too, until one day it came back to bite us quite hard ;) Admittedly we find the MSVC override keyword more useful than sealed....

Share this post


Link to post
Share on other sites
Quote:
People can override, but cannot replicate required behavior, causing the class to break.


I don't believe you ;)

struct A {
void bar() { internal_bar(); }
private:
void internal_bar() {
x += 1;
}
int x;
};
struct B
: public A {
void bar() { std::cout << "moo"; }
};



Which is the same problem that bagder82 is trying to solve....

Share this post


Link to post
Share on other sites
Why do you care so much about this? What's going to break if someone overrides the function in a derived class? Since it's not virtual, they're not going to be using it polymorphically, so it won't affect code that doesn't use that specific class; and presumably the author of that class has a reason; and if it's wrong, on his head be it.

Share this post


Link to post
Share on other sites
@Zahlman

"Since it's not virtual, they're not going to be using it polymorphically"

In my example version I don't use the class polymorphically but there is definitely no reason why someone couldn't do this by accident on a class that has some of it's functions as virtual. This is what happened in the case I have.

Thanks anyway for the advice from everyone. We will probably go down the route of, "OVERRIDE THIS AT YOUR OWN PERIL" ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Don't make it virtual. If it absolutely has to be virtual, make it private and have a public function call it.

This is one of the reasons why virtual functions should never be public, only protected: you can make a virtual function private and therefore prevent any overrides.


You can override a virtual function even if it's private.


#include <iostream>

class B
{
public:
virtual ~B() { }
void call() { vcall(); }

private:
virtual void vcall() { std::cout << "B\n"; }
};

class D : public B
{
private:
virtual void vcall() { std::cout << "D\n"; }
};

int main()
{
D d;
d.call();
return 0;
}





Virtual functions shouldn't be public because in my mind at least, "virtual" means "(customisable) implementation detail". Derived classes should be allowed to change the implementation (that's the whole point), but clients shouldn't be able to access it directly.

Share this post


Link to post
Share on other sites
Quote:
Original post by badger82
Hi All,

Does anyone have any idea on how to make a derived classes member function impossible to override? For example:

*** Source Snippet Removed ***

Thanks :)


Solution:

class A
{
// Do NOT override this method.
void Foo(){};
};


Then focus on important things.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this