Sign in to follow this  
Decrius

[C++] Is this the way to go with virtuals?

Recommended Posts

Hey, Consider the following: I have a base class from which another class derives from, each derived class has a set of codelines the same for certain operations. Now, my definition of virtual is this: "The key word 'virtual' in member functions makes sure the derived class has a replacement for that function". Is that correct? I simply make a new function in the base class, with the same name (either with a pre_ or post_ prefix, to indicate it should be executed as first or as last) which should be called by derived classes to minimize dupli-code. Is this the way to go? Has C++ a build-in feature for that? Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Now, my definition of virtual is this: "The key word 'virtual' in member functions makes sure the derived class has a replacement for that function". Is that correct?


Wrong in C++: using the virtual keyword on a function enables dynamic dispatch based on the type of the object for calls to that function. The derived classes need not provide a replacement. Your definition corresponds to a pure virtual function, which does indeed require providing a replacement.

Quote:
I simply make a new function in the base class, with the same name (either with a pre_ or post_ prefix, to indicate it should be executed as first or as last) which should be called by derived classes to minimize dupli-code. Is this the way to go? Has C++ a build-in feature for that?


No. This is a fairly common approach, and unlike CLOS, C++ does not provide built-in support.

Share this post


Link to post
Share on other sites
Quote:

I simply make a new function in the base class, with the same name (either with a pre_ or post_ prefix, to indicate it should be executed as first or as last) which should be called by derived classes to minimize dupli-code. Is this the way to go? Has C++ a build-in feature for that?

If you have the functions Prefix() and/or Postfix() which must be called before and after some Operation() (respectively), a typical pattern is to make Operation() non-virtual, and call a virtual helper:

class ExampleBase {
public:
void Operation() {
Prefix();
ImplementOperation();
Postfix();
}

protected:
virtual void ImplementOperation();

private:
void Prefix();
void Postfix();
};


This way, the client (derived) class can override the behavior of Operation as needed, but does not have to remember to call the 'required' prefix and postfix methods, which makes extending the class less error prone. Obviously this can only work if those methods have to be called.

Also keep in mind that while eliminating code duplication is a good thing, inheritance should be when it actually makes sense from a logical or semantic standpoint with respect to your object model. It should not be abused simply as a way to avoid repeating code.

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
Also keep in mind that while eliminating code duplication is a good thing, inheritance should be when it actually makes sense from a logical or semantic standpoint with respect to your object model. It should not be abused simply as a way to avoid repeating code.


Quoted for emphasis. In my extensive personal experience, composition and delegation is a far more common way of achieving code reuse in sane OO systems.

Share this post


Link to post
Share on other sites
Ah okay, thanks :)

I thinks it's hard to find dupli-code that does not "actually makes sense from a logical or semantic standpoint with respect to your object model".

And, jpetrie, while you model looks much better for derived variants, it requires an additional function call.

The functions are around 3 to 5 lines of code, so I might aswell put them in the derived classes as raw code, they won't change...unless I refactor the design ^^.

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