代码之家  ›  专栏  ›  技术社区  ›  Koldar

为什么我不把所有的东西都放在头上?[复制品]

c++
  •  0
  • Koldar  · 技术社区  · 7 年前

    这个问题已经有了答案:

    我开始用C++工作,我来自C和Java。我知道,在C中,在源代码的头和变量/类型/函数定义中编写变量/类型/函数声明是非常可取的;因此,当我在C++中开始编码时,我也想遵守同样的约定。

    Unluckly,对我来说,C++中有几个例外,在其他规则中:

    • 模板类;
    • 内联函数;
    • constexpr函数;

    这使我在文件中产生了一些混乱:其中大多数是 *.cpp 包含少量中/大成员函数的文件。

    所以我的问题是: 假设只使用类而不是普通的C代码,为什么我不能将所有内容都放在头中,并且没有cpp文件呢? (Java风格的类型);澄清:我将主要处理类,模板类,最多模板函数。

    例如在 Foo.hpp :

    class Foo {
    public:
     foo() {
         //body
     }
     bar() {
         //body
     }
    }
    

    而不是在 *.hpp *CPP :

    //file Foo.hpp
    class Foo {
    public:
     foo();
     bar();
    }
    
    //file Foo.cpp
    Foo::foo() {
       //body
    }
    Foo::bar() {
       //body
    }
    

    当然,像静态全局变量之类的东西会被放入 .*cpp 但据我所知,它们是 要求放入CPP (他们的使用也受到强烈的限制)。

    你能告诉我这种方法的缺点是什么吗?作为C++初学者,我肯定忽略了一些重要的因素。在我幼稚的观点中,CPP文件中不需要任何内容(当然,假设我只使用类进行编码)。

    谢谢

    1 回复  |  直到 7 年前
        1
  •  5
  •   eerorika    7 年前

    为什么我不能把所有东西都放在头上而没有cpp文件呢?

    好吧,你 必须 至少有一个源文件,否则就没有要编译的内容。

    但是,要回答, 为什么不把所有的东西都放在一个源文件中呢? :因为源文件的大小线性增加到整个程序的大小(拆分为头文件不会减小大小)。相关的是预处理后的尺寸)。因此,(重新)编译它变得越来越慢,对源文件的任何部分(即整个程序的任何部分,也包括头文件)的任何更改都要求您重新编译该源文件(即整个程序)。

    如果将程序拆分为多个源文件,则只需重新编译修改过的源文件。对于大型项目,这可以将一小时的编译时间缩短到一分钟,当典型的工作流为“编辑->编译->调试->编辑->编译->…”时,这是一个好消息。

    动态链接可以进一步提高这一优势:即使没有重新链接,也可以简单地替换动态库(只要新版本与ABI兼容)。


    为了公平起见,我还要回答 为什么? 应该 您将所有内容都放在一个源文件中 :因为它减少了编译时间 从头开始 . 如果您的工作流不适用于增量重新构建,那么将完整编译时间减少一点总比什么都不减少要好。因为它允许更好的优化,因为编译器不能跨源文件进行内联扩展(如果可以依赖于它的可用性,链接时间优化可能会降低这一优势)。


    理想的解决方案可能既不是在单个大型源文件中定义所有函数,也不是在每个单独的源文件中定义所有函数的理想方案。理想的选择可能介于两者之间。

    一个典型的约定是为每个类的成员函数提供一个单一的源文件,但是没有绝对的理由要遵循这个约定。在一个源文件中定义多个类的成员函数是完全好的,并且只要您有这样做的参数,就可以将一个类的定义成员函数划分为单独的文件。


    我认为这种方法“方便”,因为您不再查找函数:它在cpp文件中;该死的不是:它是一个模板,所以它在头中……真让人沮丧!

    与编译时的考虑相比,这不是一个有力的论据。开发环境是可用的(即使是免费的,而且已经存在几十年了),它允许您在不到一秒钟的时间内跳转到函数声明(或调用)的定义。