【问题标题】:C++ Do I have to include standard libraries for every source file?C++ 我必须为每个源文件包含标准库吗?
【发布时间】:2014-11-10 07:58:29
【问题描述】:

我现在有点困惑,因为我计划第一次在我的一个项目中包含多个源文件和头文件。
所以我想知道这是否是正确的方法?
我必须在每个直接使用它的源文件中包含字符串头吗?
Visual C++ 希望我包含的“stdafx.hpp”标头又如何呢?

这就是要走的路吗?

ma​​in.cpp

#include "stdafx.hpp"
#include <string> //?
#include <stringLib1.h>
#include <stringLib2.h>
using std::string;

//use a windows.h function here
//use a stringLib1 function here
//use a stringLib2 function here

stringLib1.h

#include "stdafx.hpp"
#include <string>
using std::string;

class uselessClass1
{
public:
    string GetStringBack1(string myString);
};

stringLib1.cpp

#include "stdafx.hpp"

string uselessClass1::GetStringBack1(string myString) {
    return myString;
}

stringLib2.h

#include "stdafx.hpp"
#include <string>
using std::string;

class uselessClass2
{
public:
    string GetStringBack2(string myString);
};

stringLib2.cpp

#include "stdafx.hpp"

string uselessClass2::GetStringBack2(string myString) {
    return myString;
}

【问题讨论】:

  • 是的,您必须在要使用的每个文件中包含头文件。但是,您不应在标题中使用 using 关键字。这不是很好的风格。
  • @cell 我希望这是一个讽刺的评论,你不是认真的。
  • 在每个包含标题的 c 文件中,using 也将包含在内。这可能会产生一些糟糕的命名冲突。
  • 在头文件中添加using语句是导致namespace pollution的最快方法之一
  • @Cyber​​ 这不是风格问题。

标签: c++ include header-files standard-library precompiled-headers


【解决方案1】:
  1. 一个好的做法通常是只包含您的代码在每个文件中使用的内容。这减少了对其他头文件的依赖,并且在大型项目上,减少了编译时间(还有助于找出依赖于什么)

  2. 在你的头文件中使用include guards

  3. 不要通过polluting全局命名空间导入所有内容,例如

    using namespace std;
    

    而是在需要时限定您打算使用的内容

  4. 您的项目unless you're using precompiled headers 中不需要stdafx.h。您可以在 VS 项目属性中控制此行为(C/C++ -> Precompiled Headers -> Precompiled Header

【讨论】:

    【解决方案2】:

    如果在 VS 中启用了预编译头,则需要 stdafx.h 头。 (Read this one) 您只需将stdafx.h 作为第一个包含在您的.cpp 文件中。

    关于头文件和 cpp 文件(成对出现),在头文件中包含声明所需的内容,并在 cpp 中包含其他所有内容(定义所需的内容)。在其 cpp 对中也包含相应的标头。并使用include guards

    myclass.h

    #ifndef MYCLASS_H  // This is the include guard macro
    #define MYCLASS_H
    
    #include <string>
    using namespace std;
    
    class MyClass {
        private:
          string myString;
        public:
        MyClass(string s) {myString = s;}
        string getString(void) {return myString;}
        void generate();
    }
    

    myclass.cpp

    #include <stdafx.h>  // VS: Precompiled Header
    // Include the header pair
    #include "myclass.h" // With this one <string> gets included too
    // Other stuff used internally
    #include <vector>
    #include <iostream>
    
    void MyClass::generate() {
        vector<string> myRandomStrings;
        ...
        cout << "Done\n";
    }
    
    #endif
    

    那么在main(...)中,你可以只包含myclass.h并调用generate()函数。

    【讨论】:

      【解决方案3】:

      stdafx 包含应该在每个 .cpp 文件的顶部,而不应该在 .h 文件中。 如果你不想把它放在其他每个文件中,你可以把 #include 放在 stdafx.h 中。

      【讨论】:

      • 可以依靠 stdafx 为您提供通用标头,当然很多开发人员都这样做,但我希望他们不会(我希望有一个 VS 切换到认为这是一个错误)。问题是很难在不同项目之间重用文件,因为每个项目都有不同的 stdafx。
      • 是的,但是你可以在遇到错误时轻松添加缺少的标题,不是吗?
      • 是的,但是如果是其他部门的另一个人在从事不同的项目,碰巧与您的发现共享代码,那么情况就变得政治化了! :)
      【解决方案4】:

      我想您必须拥有自己的头文件,这可能在其他 cpp 文件和头文件中也需要。就像你给的那个

      #include <stringLib1.h>
      #include <stringLib2.h>
      

      在我看来,最好创建一个通用头文件,其中包含所有通用库头文件和项目头文件。这个文件然后你可以包含在所有其他的 cpp 文件和头文件中。并且最好也使用头部保护。

      所以,考虑一个常见的头文件“includes.h”。

      #ifndef INCLUDES_H
      #define INCLUDES_H
      
      #include <string>
      
      #include <stringLib1.h>
      #include <stringLib2.h>
      
      /***Header files***/    
      
      #endif  //INCLUDES_H
      

      现在这是您的通用头文件。这可以包含在所有项目文件中。

      【讨论】:

      • 多么可怕的想法。除非您要预编译此标头,否则您到底为什么要在每个翻译单元中不必要地包含所有标头?!
      • 我想你从来没有参与过大型 C++ 项目。这个想法很快就被证明是人间地狱
      • 事实上,在我公司,这种方法是遵循的。既然你们已经指出这不是一个好方法,我会进一步研究它。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      相关资源
      最近更新 更多