编译时多态性解决方案
C++11 - Compile time Polymorphism solutions
假设我正在编写一个跨平台库,我必须以一种不同平台有不同行为的方式组织代码,这种行为(或定义)是在编译时根据我的库正在编译的平台选择的。
在c++中这样做的"通常"方法是在编写方法或类时用大量的#ifdef
污染代码。
方法的问题是:
- 源代码看起来真的很丑
- 如果你支持3个平台,你的源代码大约是你真正需要的3倍大,这意味着你的编译器仍然需要解析和分析所有的代码来"看到"
#ifdef
- 不同的实现之间没有真正的区别,当代码库增长时很难维护,当你只有3-4个平台时,它增长得非常快。
由于c++ 11中有很多新特性,我想知道是否有什么改变,如果有新的选项。
您应该使用构建系统来完成此操作。应该在头文件中提供与平台无关的函数声明和类定义。然后,根据目标平台,构建系统应该编译这些函数和类的适当实现。
例如,让我们考虑创建用于显示图形或GUI元素的窗口。如果您不使用库来完成此操作,则必须自己编写跨平台代码。首先,您应该考虑与平台无关的接口应该是什么。也许你有一个window
类和一些辅助函数。然后,您可以在头文件中提供该类的定义和辅助函数的声明,并为每个平台提供单独的实现。然后你会得到一组像这样的文件:
-
window.h
-
window_wayland.cpp
-
window_winapi.cpp
-
window_x11.cpp
现在,需要使用类和函数的所有文件都应该只是#include <window.h>
。它们都有相同的函数声明。但是,您可以在构建系统的配置中指定window_x11.cpp
应该在带有X11窗口系统的系统上编译,window_wayland.cpp
应该在带有Wayland的系统上编译,window_winapi
应该在Windows上编译。这意味着,根据您正在构建的平台,您将获得在目标平台上工作的头文件的实现。
这有几个优点:
- 您已经将构建关注点(您正在构建的平台)从代码关注点中分离出来。
- 每个平台相关的实现都有自己的文件。
- 你不会有一个混乱的预处理器指令和难以跟踪执行路径的文件。
这并不意味着使用定义有选择地编译代码的不同部分有什么问题。我更愿意看到只有少量的代码已经本地化到平台相关的部分。理想情况下,将与平台相关的代码包装在一个函数中,并让#ifdef
替换出实现。
确切地说,你如何做这个选择性构建取决于你正在使用的构建系统。对于GNU构建系统,您可以使用automake实现条件编译。文档中给出了一些示例。一个简单的例子是:
bin_PROGRAMS = hello
if LINUX
hello_SOURCES = hello-linux.c hello-common.c
else
hello_SOURCES = hello-generic.c hello-common.c
endif
使用此配置运行automake
将生成适当的makefile。
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- C++ 泛型和多态性:这种模式可行吗?
- 为什么我们实际上需要运行时多态性?
- 如何在这个简单的最小示例中实现多态性?
- 使用多态性解决代码重复问题
- 寻找继承/多态性替代方案的任何理由
- 需要使用模板解决运行时多态性的帮助
- 为什么不能在编译时解决运行时多态性?
- 解决这个多态性问题的最优雅的方法
- 编译时多态性解决方案
- 多态性歧义,我们能否用"default"基础来解决它们