View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Enforcing inherited classes without pure virtual functions?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

9 replies to this topic

### #1Lil_Lloyd  Members

Posted 16 January 2013 - 08:39 PM

Hi again dear community, I have another conundrum for which that I request your counsel. Heavy sounding introductions aside, I think this should be an easy to answer question.

In the realms of OOP there is a tendency to 'over generalise'. I like to use abstract classes but to derive super specific use cases from them. In this case, I have a 'static mesh' class that I'm rather proud of, because it's one of the few things I've coded myself that works as expected. I'm sure many programmers have similar classes in their collection.

Up until now I've been merely playing around with the staticMesh class, setting shaders and shader uniforms in calling code and then calling the 'render' function from the calling code. However, now that my codebase is scaling up in terms of sophistication, I would like to create specific classes that inherit from staticMesh like "palmTreeMesh" that will use a vertexBasedLighting shader (no significant specular term to speak of)

and so will use a render function as follows:

//pseudo code!

void PalmTree::Render()
{

StaticMesh::Render();
}

StaticMesh::Render() has no business having its code cut and pasted into several different files, it's great how it is.

So the main crux of my inquiry is thus:

StaticMesh::Render is not 'pure virtual' so static mesh is not a abstract class. However I'd like to enforce use of inherited, specific meshes

and not messy, lazy code where everything is done in a calling class. How do I do this? Just use a pure virtual 'stub' like so:

class BaseClass
{
public:
virtual void DoSomething();
virtual void Stub() = 0;
};

class Derived : public BaseClass
{
public:
void DoSomething();
void Stub() {};      //declaration and definition of 'stub'
};

Or is there another alternative to this? Thanks in advance.

### #2ApochPiQ  Moderators

Posted 16 January 2013 - 08:49 PM

Here's one common approach:
class Widget
{
public:
void DoSomeStuff()
{
CommonBeginningStuff();
InternalStuff();
CommonFinishingStuff();
}

protected:
virtual void InternalStuff() { }

private:
void CommonBeginningStuff();
void CommonFinishingStuff();
};

class SpecificWidget : public Widget
{
protected:
virtual void InternalStuff()
{
// Specificity goes here!
}
};

Wielder of the Sacred Wands

### #3Servant of the Lord  Members

Posted 16 January 2013 - 09:10 PM

You could make the base class constructor protected; then only inherited classes can access the base class' constructor, so no non-derived classes can construct the base class. Constructing a MyBase directly then gives the warning: "'MyBase::MyBase()' is protected".

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #4ChaosEngine  Members

Posted 16 January 2013 - 09:35 PM

Another way would be to mark the destructor of StaticMesh pure virtual, but also provide an implementation.

class StaticMesh
{
virtual ~StaticMesh() =0
{}
}

This forces people to implement derived classes for StaticMesh.

Yet another option would be to mark StaticMesh::Render as pure virtual (again leaving the implementation of it intact). This forces inheritors to override Render but still allows them to call the base implementation, although some people will find this confusing.

Personally, I'd go with ApochPiQs solution as it communicates the intent most clearly.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

### #5swiftcoder  Senior Moderators

Posted 16 January 2013 - 10:45 PM

POPULAR

Up until now I've been merely playing around with the staticMesh class, setting shaders and shader uniforms in calling code and then calling the 'render' function from the calling code. However, now that my codebase is scaling up in terms of sophistication, I would like to create specific classes that inherit from staticMesh like "palmTreeMesh" that will use a vertexBasedLighting shader (no significant specular term to speak of)

I'm assuming that this is an intentionally contrived example, but on the off chance it isn't...

Inheritance is generally speaking the wrong tool for the job in this case. It's not terribly useful to say that a PalmTree is a mesh, one would prefer to think of it as PalmTree has a StaticMesh and a Shader - i.e. composing multiple objects, rather than inheriting from either one.

This let's you get away from the overgeneralisation. A StaticMesh is solely responsible for drawing it's own geometry, a Shader is solely responsible for setting graphics state, and so on...

Tristam MacDonald - Software Engineer @ Amazon - [swiftcoding] [GitHub]

### #6Servant of the Lord  Members

Posted 17 January 2013 - 12:38 PM

Another way would be to mark the destructor of StaticMesh pure virtual, but also provide an implementation.

...

Yet another option would be to mark StaticMesh::Render as pure virtual (again leaving the implementation of it intact). This forces inheritors to override Render but still allows them to call the base implementation, although some people will find this confusing.

That's pretty odd! Is that valid C++?

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #7Brother Bob  Moderators

Posted 17 January 2013 - 12:55 PM

Another way would be to mark the destructor of StaticMesh pure virtual, but also provide an implementation.

...

Yet another option would be to mark StaticMesh::Render as pure virtual (again leaving the implementation of it intact). This forces inheritors to override Render but still allows them to call the base implementation, although some people will find this confusing.

That's pretty odd! Is that valid C++?

Sure. There's nothing with pure virtual functions that stops you from providing an implementation and calling it.

In fact, a pure virtual destructor is required to have an implementation and to have it called. Not required by the language syntax, but a derived class' destructor will call its base class' destructor. If you don't provide an implementation for the destructor, you'll get an undefined external symbol linker error.

### #8ChaosEngine  Members

Posted 17 January 2013 - 04:26 PM

That's pretty odd! Is that valid C++?

Sure. There's nothing with pure virtual functions that stops you from providing an implementation and calling it.

In fact, a pure virtual destructor is required to have an implementation and to have it called. Not required by the language syntax, but a derived class' destructor will call its base class' destructor. If you don't provide an implementation for the destructor, you'll get an undefined external symbol linker error.

That was my opinion as well. I'd read before that it was valid, just obscure, but I just checked my copy of the C++03 standard and now I'm not sure.

C++ Standard - section10.2
[Note:a function declaration cannot provide both a pure-specifier and a definition—end note]
[Example:
struct C {
virtual void f() = 0 { }; //ill-formed
};
—end example]

Any language standard experts care to clarify?

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

### #9Brother Bob  Moderators

Posted 17 January 2013 - 04:45 PM

It means that you cannot put both the definition and the pure specifier on the declaration, not that a pure function cannot be defined. Solution:
struct C {
virtual void f() = 0;
};

void C::f() {
}

edit: And yeah, that was new to me, actually. I thought you could do both, but MSVC doesn't complain about it even with language extensions disabled. Looks like G++ is doing the right thing though.

Edited by Brother Bob, 17 January 2013 - 04:48 PM.

### #10Lil_Lloyd  Members

Posted 17 January 2013 - 06:14 PM

I've followed swift coder's advice - namely PalmTree HAS a mesh and a shader. Actually makes everything less of a headache than what I was trying. Interesting discussion though!

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.