【问题标题】:Using std in header files在头文件中使用 std
【发布时间】:2017-05-31 06:31:33
【问题描述】:

是否有任何选项可以在不使用任何#include 语句的情况下在头文件中使用 std?我在头文件中有一个类,如下所示;

class Sequence{
private:
    std::string sequence;
    unsigned length;
public:
    /* Constructors */
    Sequence (void);
    Sequence (std::string, unsigned);
    Sequence (const Sequence &);

    /* Destructor Definition */
    ~Sequence(){}

    /* Overloaded Assignment */
    Sequence & operator
        = (const Sequence &seq)
    {
        sequence = seq.sequence;
        length = seq.length;
        return *this;
    }

    /* Setter and Getter Functions */
    void setSequence(std::string);
    void setLength(unsigned);
    std::string getSequence(void);
    int getLength(void);
};

如果不包含 iostream,则无法正确编译。但是,我在相关问题中阅读了一些 cmets,其中我们不应该在头文件中包含库和另一个头文件。那么?

【问题讨论】:

  • 你有两个选择:要么在你的头文件中包含你需要的头文件。或者确保在包含头文件之前将依赖项包含在源文件中。哪个最好?两者都一样好,你选择哪一个取决于个人喜好。
  • “我们不应该在头文件中包含库和其他头文件” 该建议不适用于标准库。您必须包含在这种情况下使用的标头#include <string>。只有forward declarations,您才能避免其他包含。
  • 如果您在界面中使用std::string,将它包含在使用它的源文件中并不同样好,因为您必须确保每次使用标题时都包含它。这包括客户端代码。
  • @SomeProgrammerDude “两者都一样好” 几乎没有。一个要求我仔细整理我的包含语句,经常挖掘多层试图弄清楚。 头文件应该是完全独立的,包括它们所引用类型的所有头文件。这就是我们包含守卫的原因。
  • @omerfaruk 一些系统头文件可能包含其他系统头文件,但它是特定于实现的东西。如果你需要std::string,那么你应该包括<string>。此外,源代码的包含部分充当一种关于您所依赖和使用的文档的文档。

标签: c++ std header-files iostream


【解决方案1】:

如果在您自己的标头 A 中依赖于类型定义或来自另一个标头 B(无论是标准标头还是其他标头)的函数声明,那么您必须在标头 A 中包含标头 B。

一般来说,你无法避免它。在某些情况下,您可能只依赖于类型的声明,在这种情况下,您可以通过使用前向声明来避免包含定义。但是,这不适用于标准库中的类型,因为它们位于您可能不声明任何内容的命名空间中。

不包含iostream就编译不正确

实际上,您的类定义取决于<string><iostream> 可能包含 <string>,但您不能依赖它。改为包含 <string>,因为您使用的是在此处定义的类型 (std::string)。

我们不应在头文件中包含库和其他头文件。

您必须包含您所依赖的所有标头,无论它们是否来自库。同时包含库头文件和其他头文件没有任何问题。

【讨论】:

  • 我明白了。我必须在头文件中包含我需要使用的库和头文件。没有其他选择,但它会影响代码的性能或其他指标吗?
  • 实际上,在这种情况下,“必须”被定义为“你真的应该这样做以保持你的理智”而不是“你的代码将无法正常工作” .
  • 从内存和性能的角度来看,使用 char *pointers 而不是字符串对象更好?如果我有许多来自一个类的对象,并且想将它们存储在一个数组中,我应该动态地(使用指针数组)还是以静态方式定义这个数组?我是C++新手,一开始想了解专业的指标/方法。
  • @omerfaruk 如果您依赖于某些定义或声明,那么除了包含这些定义和声明之外别无选择。由于别无选择,因此没有什么可以比较性能的。 “我必须包含库和头文件”是什么意思?您只包含标题。库可能会提供您可以使用的头文件。如果您有新的不相关问题,请在您自己研究过该主题后随时在 stackoverflow 上提问。
  • @user2079303 在搜索之前我没有问任何问题。首先,您没有回答我关于用于定义新的类对象数组的方法的问题?其次,我的意思是iostream和一个类文件分别作为一个库和一个头文件...
【解决方案2】:

有时您可以使用前向声明。查看前向声明以获取更多信息。如果您不能使用前向声明,则必须在翻译单元中使用之前包含所需的标头。例如,如果标题 A 依赖于标题 B,则必须在 A 在翻译单元中使用它之前包含 B。有两种方法可以实现:

  1. 在标题 A 的顶部包含 B。
  2. 或者:在所有包含 A 的地方,在 A 之前包含 B。

但是,标头应该自包含,因此首选方法 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 1970-01-01
    相关资源
    最近更新 更多