使用#ifdef是正确的策略吗?
Is Using #ifdef a correct strategy
所以,我有一个要求,做一个特定的任务(说多线程)是完全依赖于操作系统(或像win32/linux api调用)。
现在我在某处读到,使用#ifdef我们实际上可以编写与os相关的代码
#ifdef __linux__
/*some linux codes*/
#endif
现在我的问题是....
这是正确的方式来写我的代码(1)。E使用ifdef),然后释放一个单一的。cpp文件为Windows和linux?或者我应该把我的代码分成两部分,发布两个不同的版本——一个用于linux,一个用于windows?
编辑:似乎问题太宽泛了,这产生了很多意见。
根据性能、构建大小等(我可能忽略的任何其他因素)区分我提到的两种方法。
Class A {
.
.// Some variables and methods
.
};
class B: public A {
void DoSomething() {
// COntains linux codes and some windows code
}
};
如果假设我不使用#ifdef
,我将如何编写dosomething()
方法,在正确的时间调用正确的代码
解决方案#1:使用现有的、经过调试的、文档化的库(例如boost)来隐藏平台差异。它在内部使用了很多#ifdef,但是你不必担心。
解决方案#2:编写自己的独立于平台的库(参见解决方案#1以获得更好的方法),并隐藏所有的#ifdef。
解决方案#3:在宏中完成(呃,但请参阅ACE(尽管ACE的大部分也在库中)
解决方案#4:每当出现平台差异时,在整个代码中使用#ifdefs。
解决方案#4适用于非常小的、一次性的代码程序。如果你在20世纪90年代编程,解决方案#3是合适的。
解决方案#2只适用于由于非技术原因不能使用真正的库的情况。
结论:使用解决方案#1
这是可能使用#ifdef
,但它很快导致不可维护的代码。一个更好的解决方案是抽象功能放入一个类中,并提供两个不同的该类的实现(两个不同的源文件)。(即使在C语言时代,我们也会在一个头文件,并为它们提供不同的源文件实现。)
我通常给源文件相同的名称,但put它们在平台相关的目录中,例如:thread.hh
Posix/thread.cc
和Windows/thread.cc
中的源。或者,您可以将实现放在文件中不同的名称:posix_thread.cc
和windows_thread.cc
.
如果你需要在头文件中使用依赖项,可以使用目录方法同样适用。或者你可以这样写:
#include systemDependentHeader(thread.hh)
,其中systemDependentHeader
是一个宏,它做一些标记粘贴(使用命令行上定义的令牌)和stringizing .
boost::thread
离标准并不远(我认为)。更多的一般来说,如果你能找到已经完成的工作,你应该这样做好好利用它。(但要验证库的质量第一。过去,我们不得不放弃使用ACE,因为它bug太多了
如果你需要为不同的平台开发代码,你必须考虑以下几点:
您可以使用#ifdef or #if defined(x)
,但您必须将其限制在头文件中,如果该文件名为"platform.h"则更好。在源代码中,可以使用platform .h文件中定义的宏。因此,您的业务逻辑在两个平台上是相同的。
让我给你一个例子:
PLATFORM.H
// A platform depended print function inside platform.h file
#if defined( _EMBEDDED_OS_ )
#include <embedded_os.h>
#define print_msg(message) put_uart_bytes(message)
#elif defined( _WINDOWS_ )
#include <windows.h>
#define print_msg(message) printf(message)
#else
#error undefined_platform
#endif
SOURCE.CPP
void main()
{
print_msg("Ciao Mondo!");
}
正如您所看到的,每个平台的源代码都是相同的,您的业务逻辑没有被几个#ifdef指令弄脏
- #ifdef和未声明的标识符
- C++17中的并行执行策略
- C++ Macros #ifdef
- 运行时执行策略不同
- 编译器上的策略数据结构不起作用
- 我应该在简单的策略游戏中为各个派系使用类吗 - C++
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 没有执行策略的 std::transform_reduce 是可移植的吗?
- C++ 运算符修改/元编程策略,用于不那么冗长的语法
- 更新 #ifdef 中的现有变量值?
- 使用 constexpr 替换 #define 和 #ifdef 进行条件编译
- 使用 Qt5 SQL 进行异步数据库访问的策略
- C++基于策略的设计:继承与组合
- 使用 #ifdef 时的多个定义
- 使用 [#define & #ifdef] 跨文件激活代码块
- 当PSO细粒度策略对使用AdsGetObject MSDN API的Windows操作系统生效时,如何获取用户密码到期日
- 以下 OpenCV 源代码中是否存在错误?(#ifdef 没有 #else)
- 如何在源代码中使用执行策略检测 C++17 的扩展内存管理算法的可用性?
- 使用#ifdef是正确的策略吗?