teodron
teodron

Reputation: 1438

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 :) ).

Upvotes: 6

Views: 3767

Answers (4)

James Kanze
James Kanze

Reputation: 153909

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.

Upvotes: 5

bitmask
bitmask

Reputation: 34628

Yes, as others have stated you basically use classes with pure virtual (abstract) member functions and no data members. When implementing this interface, naturally you have to provide these methods.

This, on the other hand has nothing to do with dynamic allocation. Whether you have automatic objects (i.e. stack) or dynamic objects (i.e. heap) is irrelevant for how you use them, including polymorphy. Do you mean dynamic binding?

Now, having said all that, you can implement an interface without using dynamic binding (i.e. "polymorphism") with templates. Basically, you would use SFINAE+CRTP to check if a given member function exists by privately inheriting from a template class. Basically, your parent class (which contains no virtual members) template <typename T> class FooIface; (inherited from as class Foo : private FooIface<Foo>) would make sure T has the member function foo by trying to call it. Using meta-programming tricks you can also make sure foo has the correct type.

But this would probably be too cumbersome and too hard to read. An abstract base class is the common approach.

Upvotes: 4

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

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
}

Upvotes: 5

Alok Save
Alok Save

Reputation: 206518

There is no concept of Interface in C++,
You can only simulate the behavior using an Abstract class.
Abstract class is a class which has atleast one pure virtual function, One cannot create any instances of an abstract class but You could create pointers and references to it. Also each class inheriting from the abstract class must implement the pure virtual functions in order that it's instances can be created.

Dynamic allocation and Polymorphism are not related!

Dynamic allocation defines where the object will be allocated and that the object shall have explicit memory management unlike the implicit memory management provided for automatic variables.

Polymorphism means multiple forms of one thing. That is same function having different behaviors in classes.You can have a Base class pointer pointing to an object on stack and still have polymorphic behavior.

Upvotes: 1

Related Questions