c++ - 为什么要有头文件和 .cpp 文件?

标签 c++ header-files

就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the help center寻求指导。




9年前关闭。
社区在 5 个月前审查了是否重新打开此问题并将其关闭:

原始关闭原因未解决





为什么 C++ 有头文件和 .cpp 文件?

最佳答案

C++ 编译
C++ 中的编译分两个主要阶段完成:

  • 第一个是将“源”文本文件编译为二进制“目标”文件:CPP 文件是编译后的文件,并且在不了解其他 CPP 文件(甚至库)的情况下进行编译,除非通过原始声明或标题包含。 CPP 文件通常编译成 .OBJ 或 .O“对象”文件。
  • 第二个是将所有“对象”文件链接在一起,从而创建最终的二进制文件(库或可执行文件)。

  • HPP 在所有这些过程中的位置如何?
    一个可怜的孤独的CPP文件......
    每个 CPP 文件的编译独立于所有其他 CPP 文件,这意味着如果 A.CPP 需要 B.CPP 中定义的符号,例如:
    // A.CPP
    void doSomething()
    {
       doSomethingElse(); // Defined in B.CPP
    }
    
    // B.CPP
    void doSomethingElse()
    {
       // Etc.
    }
    
    它不会编译,因为 A.CPP 无法知道“doSomethingElse”的存在......除非 A.CPP 中有声明,例如:
    // A.CPP
    void doSomethingElse() ; // From B.CPP
    
    void doSomething()
    {
       doSomethingElse() ; // Defined in B.CPP
    }
    
    然后,如果您有使用相同符号的 C.CPP,则复制/粘贴声明...
    复制/粘贴警告!
    是的,有问题。复制/粘贴是危险的,并且难以维护。这意味着如果我们有一些方法可以不复制/粘贴,并且仍然声明​​符号会很酷......我们该怎么做?通过包含一些文本文件,通常以 .h、.hxx、.h++ 或我更喜欢的 C++ 文件后缀 .hpp 为后缀:
    // B.HPP (here, we decided to declare every symbol defined in B.CPP)
    void doSomethingElse() ;
    
    // A.CPP
    #include "B.HPP"
    
    void doSomething()
    {
       doSomethingElse() ; // Defined in B.CPP
    }
    
    // B.CPP
    #include "B.HPP"
    
    void doSomethingElse()
    {
       // Etc.
    }
    
    // C.CPP
    #include "B.HPP"
    
    void doSomethingAgain()
    {
       doSomethingElse() ; // Defined in B.CPP
    }
    
    include如何工作?
    从本质上讲,包含文件将解析其内容,然后将其内容复制粘贴到 CPP 文件中。
    例如,在以下代码中,带有 A.HPP header :
    // A.HPP
    void someFunction();
    void someOtherFunction();
    
    ...来源B.CPP:
    // B.CPP
    #include "A.HPP"
    
    void doSomething()
    {
       // Etc.
    }
    
    ... 包含后将变为:
    // B.CPP
    void someFunction();
    void someOtherFunction();
    
    void doSomething()
    {
       // Etc.
    }
    
    一件小事——为什么在 B.CPP 中包含 B.HPP?
    在当前情况下,这不是必需的,B.HPP 有 doSomethingElse函数声明,B.CPP 有 doSomethingElse函数定义(它本身就是一个声明)。但在更一般的情况下,B.HPP 用于声明(和内联代码),可能没有相应的定义(例如,枚举、普通结构等),因此如果 B.CPP 可能需要包含使用 B.HPP 的那些声明。总而言之,默认情况下包含其标题的源是“好品味”。
    结论
    因此头文件是必要的,因为 C++ 编译器无法单独搜索符号声明,因此,您必须通过包含这些声明来帮助它。
    最后一句话:你应该在你的HPP文件的内容周围放置标题保护,以确保多个包含不会破坏任何东西,但总而言之,我相信上面解释了HPP文件存在的主要原因。
    #ifndef B_HPP_
    #define B_HPP_
    
    // The declarations in the B.hpp file
    
    #endif // B_HPP_
    
    甚至更简单(虽然不是标准的)
    #pragma once
    
    // The declarations in the B.hpp file
    

    关于c++ - 为什么要有头文件和 .cpp 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60264014/

    相关文章:

    c++ - 如何制作 C++ 意图列表

    c++ - "warning C4800: ' int' : forcing value to bool 'true' or 'false' "不同场景下的不同行为

    c++ - 包含文件排序策略

    包含 C 头文件的 C++ 文件

    c - 如何知道头文件里面有什么?

    c++ - 内联汇编器在 vs 2015 中给出了 c2400

    C++ 独立引用 - 有什么用?

    c++ - 动态调度到模板函数 C++

    c++ - 在 C++ (arduino) 中,我如何使用一个字段来构建另一个字段

    C++ 全局包含