i'm trying write abstraction layer let code run on different platforms. let me give example 2 classes want use in high level code:
class thread { public: thread(); virtual ~thread(); void start(); void stop(); virtual void callback() = 0; }; class display { public: static void drawtext(const char* text); };
my trouble is: design pattern can use let low-level code fill in implementation? here thoughs , why don't think solution:
in theory there's no problem in having above definition sit in
highlevel/thread.h
, platform specific implementation sit inlowlevel/platforma/thread.cpp
. low-overhead solution resolved @ link-time. problem low level implementation can't add member variables or member functions it. makes things impossible implement.a way out add definition (basically pimpl-idiom):
class thread { // ... private: void* impl_data; }
now low level code can have it's own struct or objects stored in void pointer. trouble here ugly read , painful program.
i make
class thread
pure virtual , implement low level functionality inheriting it. high level code access low level implementation calling factory function this:// thread.h, below pure virtual class definition extern "c" void* makenewthread(); // in lowlevel/platforma/thread.h class threadimpl: public thread { ... }; // in lowlevel/platforma/thread.cpp extern "c" void* makenewthread() { return new threadimpl(); }
this tidy enough fails static classes. abstraction layer used hardware , io things , able have
display::drawtext(...)
instead of carrying around pointers singledisplay
class.another option use c-style functions can resolved @ link time
extern "c" handle_t createthread()
. easy , great accessing low level hardware there once (like display). can there multiple times (locks, threads, memory management) have carry around handles in high level code ugly or have high level wrapper class hides handles. either way have overhead of having associate handles respective functionality on both high level , low level side.my last thought hybrid structure. pure c-style
extern "c"
functions low level stuff there once. factory functions (see 3.) stuff can there multiple times. fear hybrid lead inconsistent, unreadable code.
i'd grateful hints design patterns fit requirements.
you seem want value semantics thread
class , wonder add indirection make portable. use pimpl idiom, , conditional compilation.
depending on want complexity of build tool be, , if want keep low level code self contained possible, following:
in high level header thread.hpp
, define:
class thread { class impl: impl *pimpl; // or better yet, smart pointer public: thread (); ~thread(); // other stuff; };
than, in thread sources directory, define files along fashion:
thread_platforma.cpp
#ifdef platform_a #include <thread.hpp> thread::thread() { // platform specific code goes here, initialize pimpl; } thread::~thread() { // platform specific code goes here, release pimpl; } #endif
building thread.o
becomes simple matter of taking thread_*.cpp
files in thread directory, , having build system come correct -d
option compiler.
Comments
Post a Comment