标题中的字符串原型需要iostream吗?

时间:2011-10-20 18:57:37

标签: c++

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

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

Edit2:我记得在很多标题示例中看过#ifndef,我觉得这对我的问题有帮助,但我似乎无法找到一个好的解释。

4 个答案:

答案 0 :(得分:5)

stringvectoriostream分开,并且这三个都是std命名空间的一部分。您只需在头文件中对它们进行适当的限定即可。

Assignment.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_;
 };

答案 1 :(得分:2)

如果需要,可以在其他标头中包含标头,也不要创建循环依赖关系。这不是这种情况,因为<string>不是用户生成的标题。

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

答案 2 :(得分:0)

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

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

class std::string; // forward declaration

class my_class
{
    std::string* psz;
};

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

答案 3 :(得分:0)

是的,您需要添加<string>,因为std::string实际上是typedef basic_string模板的typedef basic_string<char> string;

class string;

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

{{1}}