C ++的模块概念

时间:2011-09-07 22:22:43

标签: c++ c++11

C ++仍然是一种不断发展的语言,多年来一直在为它添加新功能。

我在C ++中遗漏的一个特性是一个正确的模块概念:使用头文件的当前方法(使用条件#define来确保标题不包括两次)对我来说似乎绝对不能令人满意。

例如,在我的项目中,我们遇到的问题是我们在许多源文件中有太多“#include”,这使得编译时间不必要很长:使用Incredibuild构建我们的产品需要45分钟,即使用至少10个并行核心。因此,我们必须花费大量时间手动清理文件,即删除包含以检查它们是否真的需要。

我认为拥有一个可以

的模块概念是非常有用的
  1. 清楚地将界面与模块的实现分开;
  2. 分别编译模块的接口和主体(当前.h文件每次被包含在其他文件中时反复编译):一个工具可以读取编译的接口并告诉它是什么类型,函数,类出口;
  3. 编写工具,可以更轻松地自动重新排列导入(例如,使用Java / Eclipse,可以自动重新排列文件的所有导入)。
  4. 您认为可以定义这样的模块概念并将其集成到C ++中,还是太复杂?你知道朝这个方向做出的任何努力吗?

    修改

    感谢有关预编译标头的建议。如果可能,我会尝试一下(我们使用Visual Studio 2008)。 也许我们以错误的方式使用头文件(?)我们为每个类使用一个头文件。然后我们有一个带有类实现的cpp文件。通常我们最终得到包含30,40个头文件的cpp文件。当我们更改cpp文件时,不再需要某些包含,但很难找出哪些包含。这部分与头文件包含其他头文件的事实有关。

    我们花了太多时间重新安排导入,似乎没有可以自动执行此操作的工具。这会节省我们很多时间。

2 个答案:

答案 0 :(得分:10)

  

C ++仍然是一种不断发展的语言,并且正在添加新功能   它作为C ++ 0x开发的一部分。

C ++ 11标准has already been approvedpublished,因此不再添加任何功能。至少再过几年。

  

我在C ++中错过的一个特性是一个合适的模块概念:   使用头文件的当前方法(您使用条件文件)   似乎是#define以确保标题不包括两次   对我来说绝对不能令人满意。

有些编译器支持#pragma once以避免编写包含保护,但据我所知它是非标准的。在某些情况下,想要包括警卫; Boost.Preprocessor是一个库的示例,其中包含一些故意没有包含警卫的标头。

  

例如,在我的项目中,我们遇到的问题是我们有太多问题   “#include”在许多源文件中,编译时间   不必要的长:使用时需要45分钟来构建我们的产品   Incredibuild,即并行使用至少10个核心。因此,我们   必须花费大量时间手动清理文件,即删除   包括检查它们是否真的需要。

Stroustrup has an FAQ entry on compile-time slowness。另请阅读GotW article #7关于包含头文件的内容。你很可能包含的文件多于必要的文件。例如,您可以通过前向声明来逃避。如果您有大量的头文件,您可以尝试将它们拆分,以便您的源只包含您真正需要的声明。这可能只是你的文件结构不利于快速编译。

  

1.明确分离模块实现的界面;

我们有the PIMPL idiom(也称为编译防火墙)。即使没有它,我也没有任何麻烦将实现放在.cpp文件和.h文件中的接口(即使它不是“纯”接口)。

  

2.分别编译模块的接口和主体   (目前.h文件每次都会反复编译   包含在其他文件中):一个工具然后可以读取编译   接口并告诉它导出的类型,函数和类;

某些编译器支持您可以利用的precompiled header files

  

3.使用工具更轻松地自动重新排列导入。

我不明白你的意思。

  

您认为可以定义这样的模块概念吗?   将它集成到C ++中还是太复杂了?你知道吗?   朝这个方向努力?

信不信由你,有a proposal为C ++添加某种模块概念,但由于时间限制,它已被C ++ 11接受(他们正在努力并审查其他提议,如右值参考,在我看来,更为重要)。它可能包含在下一版本或C ++标准的更新中。

答案 1 :(得分:0)

这不是C ++的设计方式。你可能会这样做,如果你戳了戳链接足以读取索引文件而不是重新解析头文件。但是,您的编译器应该只编译已更改的文件或具有已更改的依赖项。此外,标题并没有真正“编译”成有意义的代码(除非它们在其中有实现,在某些情况下这是正确的)。它们只是编译器的一个注释,即在链接时稍后会找到该标记。

简短回答:不,你不应该尝试实施一些家庭酿造'模块'系统。我真的怀疑头文件无论如何都是永远的,除非你错误地使用它们。

编辑:正如有人指出的那样,我忽略了可能实际需要编译的头文件,这通常是大型库或任何使用大量模板的情况。因此,我对“真正怀疑头文件是永远需要的东西”的说法是错误的。