Sign in to follow this  
f8k8

C++ ABC with template functions

Recommended Posts

I'm trying to come up with a method of declaring an interface for classes for a cross platform engine. At the moment, I've got something along the lines of:
class IFoo
{
public:
#ifdef _DEBUG
    virtual void DoSomething() = 0;
    virtual void DoSomethingElse() = 0;
#else
#endif
};

So that the interface is enforced by the compiler when doing a debug build, but no unnecessary virtual tables are created when doing a release build. I'm also trying to implement functors for callbacks. For that, I've got a functor base class with a virtual "Call" function, and a templated functor class which inherits from the base and calls the registered function on the registered object. This way, I can store a list of functor base classes and call the Call() function on them, even though the objects each one calls can have unrelated types. The only problem I've got is that, while I could create a templated function for registering a callback in one of my classes, I can't figure out a way to enforce that function to be implemented using the interface, as you can't have virtual template functions. Any ideas?

Share this post


Link to post
Share on other sites
Quote:
Original post by f8k8
the interface is enforced by the compiler when doing a debug build, but no unnecessary virtual tables are created when doing a release build.
The compiler already checks to ensure a class has the necessary interface for it to function in a given program:

class Foo
{
public:
void DoSomething();
};

Foo foo;
foo.DoSomethingElse(); // Ooops, not part of the interface - caught at compile time

Of course, if DoSomethingElse was never called from within the program then the compiler would have no idea that Foo's interface is incomplete - but is that really a problem?

You can explicitly define an interface at compile time using the Curiously Recurring Template Pattern to implement static polymorphism:

template <Derived>
class IFoo
{
public:
void DoSomething() { This().DoSomethingAux(); }
void DoSomethingElse() { This().DoSomethingElseAux(); }

private:
Derived & This() { return static_cast<Derived&>(*this); }
};

// A concrete class
class DerivedFoo : public IFoo< DerivedFoo >
{
private:
friend class IFoo< DerivedFoo >; // required if auxiliary functions aren't public.

void DoSomethingAux() { }
void DoSomethingElseAux() { }
};

If any of the auxiliary functions were missing the compiler would spit errors when either DoSomething or DoSomethingElse are used.
Note, however, that if either function is never used in the program then the compiler will still be none the wiser to any missing functions, just as before.

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