ojrask
ojrask

Reputation: 2828

Cross-platform C++: wrapping OS-specifics behind a class

I'm working on a C++ project which should run on Linux and Windows 7+. This is also my first week with C++ after a very simple and short basics course some years back.

Let's say I need to access the filesystem, but as OS's have different APIs for that I need to create a wrapper class to make things consistent.

Would the following work:

Have a base class File. From file I inherit WinFile and LinuxFile, which implement the base class public methods (e.g. createFile, readFile, etc.). Then in both sub-classes I implement the public methods to map to platform specific methods (WINAPI file handling and UNIX file handling).

Then I would use a preprocessor directive to conditionally load either WinFile or LinuxFile in the main application:

int main()
{
    #if defined WIN32
    WinFile fileSystem;
    #elif defined LINUX
    LinuxFile fileSystem;
    #endif

    // Both of above contain the same public method API.

    std::string filedata;
    filedata = fileSystem.readFile(...);

    ...
}

My gut says that this should work, but are there any drawbacks? Will this become a maintainability problem easily? Are preprocessor directives considered "hacks" or something? I know they're used with header include guards and such, but they're compiler related logic, not application related logic.

Any other ways to achieve what I'm trying to do here?

Upvotes: 2

Views: 608

Answers (1)

Naios
Naios

Reputation: 1573

You could define the API in a header file and move the implementation into cpp files. Add the .cpp source files dependent on your os (or guard the .cpp files through) macros, for example:

// File.h
class File
{
public:
    void open(std::string);
};

// File_impl_win.cpp (compiled when win)
void File::open(std::string)
{
    // impl
}

// File_impl_lin.cpp (compiled when linux)
void File::open(std::string)
{
    // impl
}

The advantage is that you don't need to distinguish between a LinuxFile and WindowsFile, you got a single api instead.

But there is an amazing crossplatform boost library for filesystem usage already, boost filesystem, which you could use.

Upvotes: 1

Related Questions