Using nonvirtual inheritance for informal 'interfaces'?

Started by
17 comments, last by Matt-D 10 years, 9 months ago

Is it a good idea to make interfaces like


class Foo
{
    void bar()
    {
        assert(false); //Not implemented in derieved class, go fix nao.
    }
}

class Derieved : public bar
{
    void bar()
    {
        print("yay");
    }
}

to have some idea what methods a class should have, when i need some common functionality for the classes to be used as template args?

One problem i see is that it wont fail at compile time if something is not implemented. Is there a way to do something like this, so that a compile time failure would result if something is missing and the base class version is called instead (which will fail at runtime due to the assert)?

An obvious solution is to simply comment out the ": public bar" section.

Or do you recommend just creating some documentation in a place well hidden somewhere with outdated information as to what methods/typedefs a class should implement to be a 'valid' value for certain templates?

o3o

Advertisement

Make it an abstract function in the base.


class Foo
{
   virtual bar() = 0;
}

Also note that in your example, the bar() function will hide the base function; it must be marked virtual in order for it to work the way you expected.

I want it to hide the bases methods. This has no actual need, i just want some structure in my program.

I want a class that says that all derieving classes must implement this and this, but i dont want to use virtuals since im not intending to use the classes polymorphically.

Like i said, a solution would be to comment out the ": public Foo" part.

o3o

Right, first be aware of the differences between inheritance of virtual and non-virtual member functions.

If you want a compile time error, use virtual inheritance as Frob shows. Otherwise, if you wanted a run-time assert, or some other default action, its something of a little known fact that you actually *can* give a virtual function an implementation. Derived classes must still implement a version of that function, but they can call specifically to the base class' "default" implementation. This is probably more useful when there is a reasonable default for the method though, rather than just asserting, etc.

throw table_exception("(? ???)? ? ???");

The reason i dont want to use virtuals is because i dont need polymorphism and it would add extra overhead.

But, if i have a pure abstract base class, will there actually be any overhead (will there be a vtable?)

Can i use a pure abstract base class as a compile time enforcement to force the derieving classes to implement certain methods (although i cannot force the classes to derieve from the base class in my template functions)?

o3o

I don't really see the point. If you try calling a member function on a class that doesn't support it you'll get a compiler error even without any tricky base class usage.

I don't really see the point. If you try calling a member function on a class that doesn't support it you'll get a compiler error even without any tricky base class usage.

I know.

But i would like a way to document the code in a better way than a random comment somewhere saying what the classes need. With a base class, i have something bundling the classes into the same 'family'.

What is standard when there are requirements of classes to be used as template args? How are the requirements documented? In code, in comments somewhere, or in some external documentation? Or do you just copypaste the declaration of a working class and implement them? :P

o3o

Can you give your classes real names instead of things like "Foo"? It's very hard to discuss design decisions in a vacuum.

Generally, the documentation for the template says that the template arguments are required to satisfy certain criteria and somewhere that criteria is defined. For example, for the C++ standard library in C++03, the value types of containers are documented to be Assignable and CopyConstructible and references to where those requirements are documented are placed in the container documentation (sections 23.1 and 20.1.3 if anyone cares).

As i dont have external documentation, i shall make an "example class" with method declarations and whatever else is required (no definitions), which i dont actually use anywhere.

Itll have the added benefit of letting me copypaste it when i need a new class that works with my templates.

Until something line concepts gets added, and 5 years from that so they are actually implemented ;P

o3o

This topic is closed to new replies.

Advertisement