C ++仍然是一种不断发展的语言,多年来一直在为它添加新功能。
我在C ++中遗漏的一个特性是一个正确的模块概念:使用头文件的当前方法(使用条件#define来确保标题不包括两次)对我来说似乎绝对不能令人满意。
例如,在我的项目中,我们遇到的问题是我们在许多源文件中有太多“#include”,这使得编译时间不必要很长:使用Incredibuild构建我们的产品需要45分钟,即使用至少10个并行核心。因此,我们必须花费大量时间手动清理文件,即删除包含以检查它们是否真的需要。
我认为拥有一个可以
的模块概念是非常有用的您认为可以定义这样的模块概念并将其集成到C ++中,还是太复杂?你知道朝这个方向做出的任何努力吗?
修改
感谢有关预编译标头的建议。如果可能,我会尝试一下(我们使用Visual Studio 2008)。 也许我们以错误的方式使用头文件(?)我们为每个类使用一个头文件。然后我们有一个带有类实现的cpp文件。通常我们最终得到包含30,40个头文件的cpp文件。当我们更改cpp文件时,不再需要某些包含,但很难找出哪些包含。这部分与头文件包含其他头文件的事实有关。
我们花了太多时间重新安排导入,似乎没有可以自动执行此操作的工具。这会节省我们很多时间。
答案 0 :(得分:10)
C ++仍然是一种不断发展的语言,并且正在添加新功能 它作为C ++ 0x开发的一部分。
C ++ 11标准has already been approved和published,因此不再添加任何功能。至少再过几年。
我在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 ++的设计方式。你可能会这样做,如果你戳了戳链接足以读取索引文件而不是重新解析头文件。但是,您的编译器应该只编译已更改的文件或具有已更改的依赖项。此外,标题并没有真正“编译”成有意义的代码(除非它们在其中有实现,在某些情况下这是正确的)。它们只是编译器的一个注释,即在链接时稍后会找到该标记。
简短回答:不,你不应该尝试实施一些家庭酿造'模块'系统。我真的怀疑头文件无论如何都是永远的,除非你错误地使用它们。
编辑:正如有人指出的那样,我忽略了可能实际需要编译的头文件,这通常是大型库或任何使用大量模板的情况。因此,我对“真正怀疑头文件是永远需要的东西”的说法是错误的。