【问题标题】:String prototype in header requires iostream?标头中的字符串原型需要 iostream?
【发布时间】:2023-03-11 23:46:01
【问题描述】:

所以在我的标题中,我创建了一个字符串:string s; 编译器对此感到抓狂。我知道字符串是 iostream::std 的一部分。我是否必须将它包含在标题中而不是 .cpp 文件中?如果是这样,如果使用标头的其他文件包含 iostream,那会很糟糕吗?我该如何处理?

编辑:也适用于矢量,因为我的作业中似乎非常需要它。

Edit2:我记得在很多标题示例中都看到过#ifndef,我觉得这可能有助于解决我的问题,但我似乎找不到很好的解释。

【问题讨论】:

  • 字符串是std::string的一部分
  • 至于Edit2,那些是包含警卫,与您的问题完全无关。

标签: c++


【解决方案1】:

stringvectoriostream 是分开的,并且这三个都是 std 命名空间的一部分。你只需要在你的头文件中正确地限定它们。

分配.h

 #include <string>
 #include <vector>
 // no need to #include <iostream>

 struct Obj
 {
    // fully qualified with std::
    std::string s_;

    // same:
    std::vector<std::string> v_;
 };

【讨论】:

    【解决方案2】:

    如果需要,可以在其他标头中包含标头并且不要创建循环依赖项。这里不是这种情况,因为&lt;string&gt; 不是用户生成的标头。

    如果您将using namespace std; 添加到标题中而不是指定类型的范围,那将会很糟糕。这样做会在您包含标头的所有文件中使用 namespace std 的内容填充您的全局命名空间。

    【讨论】:

      【解决方案3】:

      如果您在自己的标头中使用 string 的标头,则确实需要包含该标头。这是因为编译器需要计算具有string 成员的对象的内存布局,这意味着它需要首先计算string 的布局,这意味着它必须查看string 的完整声明。

      没有直接的解决方法,但如果您遇到问题,您可以使用pimpl idiom 解决它。这种模式的好处之一是它允许您在类中聚合一个对象,而无需首先包含其声明(而不是前向声明该类),如下所示:

      class std::string; // forward declaration
      
      class my_class
      {
          std::string* psz;
      };
      

      当然,现在您负责构建string 并自己获取指向它的指针,并手动管理该对象。此外,访问该字符串现在需要额外的指针取消引用。

      【讨论】:

        【解决方案4】:

        是的,您需要包含&lt;string&gt;,因为std::string 实际上是typedefbasic_string 模板。

        typedef basic_string<char> string;
        

        如果它是一个类,你可以在某些情况下转发声明它而不包括它的定义。

        class string;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多