【问题标题】:Confused about the actual purpose of header files in C++ [duplicate]对 C++ 中头文件的实际用途感到困惑 [重复]
【发布时间】:2012-07-16 16:06:41
【问题描述】:

可能重复:
In C++ why have header files and cpp files?

由于两个相互矛盾的原因,我不太了解 C++ 头文件:

  1. 我认为头文件的目的通常是分离接口和实现。换句话说,客户端通过头文件来学习如何使用类,而不必担心类在内部实际上是如何实现这个功能的。

  2. 那么,为什么 C++ 类的私有变量会在其头文件中指定?

在我看来,在头文件中包含私有变量违反了接口和实现的分离。直观地说,我认为将私有变量放在源文件中会更有意义,因为这是不暴露给外界的文件。

也许我只是误解了头文件的用途,1.上面是完全错误的吗?以什么方式?

【问题讨论】:

  • 除了friend 函数,我敢打赌这只是编译器确定类大小的技术限制。
  • @DaveSwersky 这个骗子没有回答 OP 的第二个问题,“那么,为什么在其头文件中指定 C++ 类的私有变量?”
  • @Mysticial:该问题的第二个答案解决了这两点。
  • @NoobOverflow 您在第 1 点上是正确的。第 2 点也是一个好问题。大部分情况下,答案是 C++ 编译模型很烂。
  • 2 所以使用类的代码知道类有多大,所以它知道为它在堆栈上创建的实例等留出多少空间。

标签: c++


【解决方案1】:

C++ 头文件的主要功能目的是在 C++ 语言中没有模块导入或其他语言中存在的任何类似内容。编译器从其他文件中了解类型、函数等的唯一方法是使用 #include 将代码粘贴到当前源文件中。

理论上,您也可以将所有源代码放入标头中,并且只需一个包含所有标头的源文件。通常不这样做的原因是双重的。首先,编译需要更长的时间(对某些项目来说是一个重大问题),并且对任何文件的任何更改都会导致项目的完全重新编译。其次,将实现放入源文件实际上有助于将接口与实现分开,即使在头文件中仍然指定了部分实现。

请注意,标头中的内联方法还会向您的类的公共/客户端公开详细的实现细节。

如果您真的希望将接口与实现完全分开(这有一定的优点),那么 C++ 的方法就是使用 pimpl 习惯用法。使用该习语,所有私有数据都隐藏在源文件中,只向公众提供一个抽象接口。此外,使用非虚拟接口 (NVI) 模式可以进一步帮助将客户端与接口更改隔离开来。

【讨论】:

    【解决方案2】:

    C++ 区分函数和类的声明和定义。通常,C++ 头文件包含类的声明。由于不允许部分声明,因此头文件需要包含完整的类声明,包括所有私有成员(变量和成员函数)。

    如果您想对公众隐藏完整的实现,您可以使用pimpl idiom 来实现。

    【讨论】:

      【解决方案3】:

      头文件的目的是为编译器提供在编译单元(.cpp 源文件)之间共享定义所需的信息。这是机械的东西,而不是哲学的东西。

      例如,私有成员变量需要声明,因为它们定义了对象的大小,编译器在分配对象时需要知道大小。

      【讨论】:

      • 在编译单元之间“共享声明”不是正确的术语吗?经常很困惑,声明和定义的手段是什么......
      • @g-makulik,我使用的是英语意义上的“定义”,而不是正式的 C++ 用法。当然可以在标题中包含定义,例如模板几乎是强制性的。
      • 为什么只有私有成员变量?
      • @zgulser not only 私有成员变量,这只是一个例子。确实需要完整的声明。
      • @MarkRansom 谢谢马克。实际上,我很惊讶没有人提到分配(但你),因为我相信这是 C++ 必须将对象状态放在头文件中以了解堆栈分配的大小的主要原因。我想当时这是他们能想出的唯一方法。虽然 Java 把它搞砸了一点,但把所有东西都放在一个锅里。
      【解决方案4】:

      在 C/C++ 中,头文件的一个目的是允许多个翻译单元使用具有相同定义的类型,而不会在多个文件中重复定义。类的部分定义是它的私有成员。

      【讨论】:

        猜你喜欢
        • 2015-02-11
        • 1970-01-01
        • 2021-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多