限制#include指令的范围

时间:2011-02-19 00:02:57

标签: c++ scope include c-preprocessor

假设我有一个包含使用std::string的类的头文件。

#include <string>

class Foo
{
     std::string Bar;

     public:

     // ...
}

此标头文件的用户可能不希望std::string包含在他/她的项目中。那么,我如何将包含限制在头文件中呢?

4 个答案:

答案 0 :(得分:11)

您的类的用户必须包含<string>,否则他们的编译器将不知道Foo对象有多大(以及Foo的构造函数/析构函数是内联定义的,那么编译器也不会知道要为string成员调用什么构造函数/析构函数。)

这确实是C ++编译模型的一个令人恼火的副作用(基本上是从C完整继承的)。如果你想完全避免这种事情,你可能想看看PIMPL idiom

答案 1 :(得分:5)

基本上,你没有。一旦您包含了一个文件,该文件中的所有实体都可用于翻译单元的其余部分。

隐藏此类依赖关系的惯用方法是依赖pimpl idiom

那就是说,为什么使用Foo代码<string>包含std?它的所有实体都在<string>命名空间中(好吧,除了{{1}}可能包含一些C标准库头文件,但通常你应编写代码,期望可能包含C标准库头文件通过任何C ++标准库头文件。)

答案 2 :(得分:1)

我不知道如何做到这一点,或者在c ++中是否可行。原因是:当编译器看到类型为“std :: string”的成员时,它必须知道什么是类型才能知道它的大小。只能通过查看.h文件中的类定义来获取此信息。

用户可以在其源代码中使用不同字符串类的一种方法是使用“using”构造:

//This is how users can use an adt with same name but in different namespaces

    using std::string;
    string bar = "there";


    using my_own_lib::string;
    string bar1 = "here";

答案 3 :(得分:0)

你做不到。如果用户不想包含std::string,那么他或她根本不应该使用该类。项目必须包含std::string才能正确链接您的课程。