用C++编写多个平台实现

Writing multiple platform implementations in C++

本文关键字:平台 实现 C++      更新时间:2023-10-16

我的目标是为每个操作系统编写具有不同实现的函数。

有些项目是这样做的:

system.h
system_win.cpp
system_osx.cpp
system_linux.cpp
etc...

这很有道理。然后说您需要与某个操作系统相关的局部变量,您只需要创建system_win.h。这种技术会使您的代码非常可读,但会使管理每个操作系统编译的文件变得非常挑剔。

然后一些项目大量使用CCD_ 2。这种技术的问题是代码可能会变得非常混乱。

我的源代码需要可读。但也需要有意义。

什么是最好的?为什么?

您可以为用户创建system_win.h。在system.h中,使用#ifdef来确定哪个操作系统用户正在使用,并为其包含正确的标头。

C++在翻译单元中运行。许多IDE和构建系统(甚至是跨平台的IDE)都将生成的应用程序视为连接在一起的多个编译单元。根据您的描述,您希望构建一个system编译单元。所以

制作公共接口头(这里没有实现细节,一切都很好,很干净)。它包含公共接口,对链接到它的应用程序可见

// system.h
int function_open(char*);

使私有实现源

// system.cpp
int function_open(char*a)
{
#if defined(__MSWIN__)
::Create(a)
#elif defined(__OSX__)
::open(a)
#endif
}

这种技术(ifdefs)的问题是代码可能会变得非常混乱。

某些条件句是必须的。无论您是将它们作为ifdef放在源代码中,还是作为一些混乱的条件编译指令放在makefiles/meta-makefiles中。在我的实践中,我们试图将操作系统的独立性保持到尽可能低的抽象级别。我们封装了操作系统依赖性,这样其他翻译单元的其他人就不需要看到实际的实现。

明智地选择您的构建系统(例如考虑cmake)。根据您的构建系统,可能会有其他实现(例如,私有和公共标头物理上位于不同的位置)。

我建议使用特定于平台的源文件,而不是#ifdef。正如你所说,这是一种更易于管理的方法。

如果你需要特定于平台的头文件,我发现一个好方法是给它们提供相同的文件名,但将它们放在不同的特定于平台目录中:

windows/abc/foo.hpp
linux/abc/foo.hpp
osx/abc/foo.hpp

只有与目标平台对应的目录才会添加到标头搜索目录列表中。然后,您可以像往常一样包括标题,并将自动选择正确的标题:

#include <abc/foo.hpp>

如果你有一些想要在平台之间共享的通用代码,你可以创建"专用"平台特定的头文件,并使"公共"头对所有平台都是通用的:

windows/abc/detail/foo_platform.hpp
linux/abc/detail/foo_platform.hpp
osx/abc/detail/foo_platform.hpp
common/abc/foo.hpp

然后在foo.hpp:内部

#include <abc/detail/foo_platform.hpp>