所以在我的标题中我创建了一个字符串:string s;
编译器对此感到不满。我知道字符串是iostream :: std的一部分。我是否必须将其包含在标题中而不是.cpp文件中?如果使用标头的其他文件包含iostream,那么它是否会变坏?我该如何处理?
编辑:也适用于矢量,因为在我的作业中我似乎需要它。
Edit2:我记得在很多标题示例中看过#ifndef,我觉得这对我的问题有帮助,但我似乎无法找到一个好的解释。
答案 0 :(得分:5)
string
和vector
与iostream
分开,并且这三个都是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}}