C++跨平台开发,以避免预处理器指令

Sta*_*tan 9 c++ cross-platform

我需要维护一个支持在Linux和Windows上运行的项目.使用像这样的预处理器指令的一些代码很好.

#ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
#include <windows.h>
#else
#include <unistd.h>
#endif
Run Code Online (Sandbox Code Playgroud)

但有些是实际的实现,我想阻止使用预处理器指令.

void Foo()
{

    #ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
    code for windows 
    #else
    code for Linux
    #endif

    some common code...

    #ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
    code for windows again
    #else
    code for Linux again
    #endif

}
Run Code Online (Sandbox Code Playgroud)

因此事情变得复杂且难以维护.有没有更好的方法?

Mat*_*son 8

传统的方法是"隐藏"特定于包装函数中任何操作系统的所有代码 - 您可以在执行更高级别功能的完整函数中执行此操作 - 例如,具有基于给定路径返回所有目录条目的函数作为输入,或实现单独的基本的功能,例如start_read_directory(path),read_dir_entry(),end_read_directory()-这只是一个例子的功能,相同的原理(一个或多个)可被几乎所有的系统特定功能的应用上.包好它,你就无法分辨出你的编程.

从本质上讲,如果代码本身有很多#ifdef,那么你做错了.


Nem*_*vic 8

处理构建系统中的操作系统细节,而不是代码.例如,有两个版本的Foo.cpp:一个在Linux上编译,另一个在Windows上编译.理想情况下,头文件将是通用的,并且所有功能签名都相同.


J_D*_*J_D 6

您可以使用工厂模式的简化版本.

有一个共同的界面

class MyClass
{
public:
    virtual void Foo() = 0;
};
Run Code Online (Sandbox Code Playgroud)

并为每个平台创建一个特定的类

#import <windows.h>
class MyClassWindows : MyClass
{
public:
    virtual void Foo() { /* Do something */ }
};

#import <linux.h>
class MyClassLinux : MyClass
{
public:
    virtual void Foo() { /* Do something */ }
};
Run Code Online (Sandbox Code Playgroud)

然后当你需要这个课时,你使用你的工厂:

class MyClassFactory
{
public:
    static MyClass* create()
    {
        #if defined _WIN32
            return new MyClassWindows();
        #elif defined _LINUX
            return new MyClassLinux();
        #endif
    }
}
Run Code Online (Sandbox Code Playgroud)

此方法有许多变体,包括在每个特定于平台的类的.cpp中定义MyClassFactory :: create方法,并仅为相应的平台编译.cpp.这避免了所有预处理指令,通过选择正确的实现文件进行切换.

  • 这不会引入运行时虚拟功能成本以及当您永远不会同时在两个平台上运行时有点多余的继承层吗? (2认同)