因此,有第三方库需要包含头文件才能使用它。由于库的实现不是面向对象的,我编写了一个Class来封装库的所有用法,因此如果需要替换它,我只需要修改该类的实现。
由于其他开发人员将在相同的代码库中工作,我想要一种方法,如果他们包含库,就会给他们一个错误。这是为了避免在库的所有地方都有引用。
例如,如果他们这样做:
#include "cool_library.h"
他们得到一个错误说:
do not include directly cool_library.h, instead use the cool_library_wrapper class
这可能吗?我正在使用GNU GCC
答案 0 :(得分:3)
您可以在#ifndef块中使用#error预处理程序指令。
例如在原始的.h文件中有这个:
#ifndef COOL_LIBRARY_WRAPPER_CLASS_INCLUDED
#error "do not include this file directly
#endif
在包装器类的头文件中执行以下操作:
#define COOL_LIBRARY_WRAPPER_CLASS_INCLUDED
答案 1 :(得分:3)
由于您正在使用gcc
,因此您可以使用预处理器的#include_next
功能:在查找具有更高优先级的目录中创建与第三方同名的标头头文件。在您的标题版本中使用类似
#if WRAPPER_HEADER_HAS_BEEN_INCLUDED
# include_next <cool_library.h>
#else
# error ...
#endif
答案 2 :(得分:2)
只有在修改cool_library.h
文件时才可以这样做。你可以这样做:
#ifndef INCLUDED_FROM_COOL_LIBRARY_WRAPPER
#error do not include directly cool_library.h, instead use the cool_library_wrapper class
#endif
.. remainder of original cool_library.h
#define INCLUDED_FROM_COOL_LIBRARY_WRAPPER
#include "cool_library.h"
... your wrapper
#undef INCLUDED_FROM_COOL_LIBRARY_WRAPPER
当然,您仍然无法阻止您的同事自己定义INCLUDED_FROM_COOL_LIBRARY_WRAPPER
并包含原始头文件。这是一个没有技术解决方案的社会问题。
答案 3 :(得分:1)
如果您通常包含一些项目范围的标题,则可以检查第三方标题中是否存在包含保护,例如
// third_party.h
#ifndef THIRD_PARTY_H
#define THIRD_PARTY_H
...
和
// your_project_wide.h
...
#ifdef THIRD_PARTY_H
#warning "Please include "cool_library.h"
#endif
...
注意事项:#warning
是一个gcc扩展,所有这些都依赖于项目标题(which you might not want to do)之前包含的外部依赖项。
答案 4 :(得分:1)
不要将<cool_library.h>
放在正常的构建包含路径中。您可以使用特殊的CFLAGS
为您的包装器提供访问权限,也可以使用更明确的路径(如某些更高级别的包含路径中的<vendor/xyz/cool_library.h>
)来访问它。
另一种基于路径的方法是将早期的本地<cool_library.h>
置于包含路径中,并使用上面的#ifdef/#error
方法。如果存在魔术定义,那么存根头可以使用更明确的路径来获取真实头。 (如果你包含一些名称与正在读取的标题完全相同的东西,某些编译器会有一个hack继续搜索路径)