Sign in to follow this  
demonkoryu

Compile-time polymorphism methods for cross-platform C++

Recommended Posts

Let's discuss methods for compile-time polymorphism in C++.

Background: In my current toy app (a file manager), I want to keep the platform-specific implementations in their own classes and namespaces, but use them without specifying a specific namespace/implementation.

These classes share the same interface, but since the platform will be known at compile time, I don't want to use abstract factories and pay for virtual function calls (however small that cost may be).

(Note: I don't plan to port this file manager over to *nix. I'm experimenting with coding techniques to improve code quality and organization.)

For example, consider a simple debug console.


// pseudocode:
interface console {
public:
static console &getSingleInstance();

void write(const std::wstring &);
void setTitle(const std::wstring &);
void clear();

protected:
console();
}


This interface will have several implementations, for example win32::console and unix::console.
But in my app, I just want to do this:

console &con = console::getSingleInstance();


without having to worry about the current platform.

Assuming that there are many of these classes, what are the different methods to achieve this, and their pros/cons?

I came up with a few ideas how this can be done, and hope that you will criticise them.

I'm assuming a modern compiler (VC++ >= 8 or GCC >= 4.5) here, so I'm open for techniques that may work only with them.


  • Preprocessor switch in a platform-independent header pulls in different implementation? Kinda defeats the namespaces.

  • Using namespaces and pull the platform-specific classes into the platform-independent namespace via using?

  • Using templates and tag dispatching? Define a "platform" tag type (struct) and have template specializations default to this "current platform" tag?

  • Maybe there is another template-based/template metaprogramming-based approach?

  • Use abstract base classes and cast to derived type?

  • Are there other methods?



[Edited by - Konfusius on October 12, 2010 10:45:41 AM]

Share this post


Link to post
Share on other sites
Another approach: Policy Based Design.


template< typename Impl >
class IConsole : private Impl {
public:
void write( const std::wstring& msg ) {
Impl::writeImpl( msg );
}
};

class Impl1 {
protected:
void writeImpl( const std::wstring& msg ) {
// Implementation
}
};

class Impl2 {
protected:
void writeImpl( const std::wstring& msg ) {
// Implementation
}
};

#ifdef CONDITION1
typedef IConsole< Impl1 > Console;
#elif CONDITION2
typedef IConsole< Impl2 > Console;
#endif

Share this post


Link to post
Share on other sites
Quote:
Original post by Ashkan
Another approach: Policy Based Design.

*** Source Snippet Removed ***


+1, I've found this effective such that I've yet to look for another method (and I'm not sure there really is any other, this sort of stuff really must involve the preprocessor).

For anything thats particularly OS dependent I usually just use Qt, which handles things nicely (and without me having to sweat over the details).

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