Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ non-polymorphic interface

Simply put, how do you create an interface in C++ for a single level of inheritance (for simplicity and didactic reasons)? I saw some code that wasn't using polymorphism, but where the base class contained a virtual abstract method (virtual void TheMethod() = 0).

Now a class was derived from this abstract class with the pure virtual method, but in the subsequent code, instances of the derived class were used without dynamic allocation at all.

Is this the correct way to do it? What about the overhead inferred by the usage of a polymorphic design?

I presume this is out of the question.. this looks more like hiding/ghosting the base method, even if that method is a pure virtual one.

Later edit: thanking all the people that managed to provide some good answers, I'd like to underline a critical error that arose from the usage of "dynamic allocation" with the meaning of emphasizing this object creation possibility as the only one compatible with polymorphism. It is quite clear that it is not the only way (but maybe the most common?) to make use of this run-time call behavior, but to further clarify my original question:

Is there a way to force a programmer to implement a method without using pure virtual methods? My perhaps unjustified concern is whether or not having opened the gate to polymorphic design is also a bit heavy on the performance side (talking thousands of such calls per second to the method in discussion).

Even later edit: making the base have a protected constructor means it cannot be instantiated directly (apart from using factories or other friendly means) and this could solve compensate for one of the effects a pure virtual methods induces. But how to make sure any derived class still provides its own method implementation? If the maybe exaggerated concern of having an associated vtable is really not that big of a deal, I'll stick to using the pure virtual method (since SFINAE the curiously recurring template pattern is more difficult to read and understand by people that are not at least intermediate C++ programmers - like me :) ).

like image 310
teodron Avatar asked Aug 24 '12 08:08

teodron


2 Answers

You don't have to allocate an object dynamically to use it polymorphically:

struct base {
    virtual void foo() = 0;
};

struct derived : base {
    virtual void foo() {
        // do stuff
    }
};

void f(base& object) {
    object.foo();
}

int main() {
    derived object; // no dynamic allocation at all
    f(object); // polymorphism happens here
}
like image 139
Björn Pollex Avatar answered Sep 19 '22 12:09

Björn Pollex


For didactic reasons, if the goal is to understand how to implement polymorphic objects in C++, and test the types one has created, dynamic allocation isn't necessary. In a real application, however, it probably will be, since the principal reason for using polymorphism is because the concrete type will not be known until runtime.

Note that in C++ (and in practically every other language which supports it), polymorphism requires reference semantics, rather than the value semantics which C++ uses by default. Typically, a class designed to be used as a base class will not support copy and assignment (except possibly via a virtual clone() function).

With regards to the overhead: compared to what? Calling a virtual function is typically more expensive than calling a non-virtual function. But if you're using virtual functions, it is because you need runtime dispatch; simulating this using some other mechanism is likely to be even more expensive.

like image 33
James Kanze Avatar answered Sep 21 '22 12:09

James Kanze