std::ostream 在不定义头文件的情况下识别。
std::ostream 在不定义头文件的情况下识别。
我创建了这段代码:
Main.cpp
#include#include "Quote.h" int main() { derived().print(std::cout); getchar(); return 0; }
Quote.h
#pragma once #includeclass base { public: std::string name() { return basename; } virtual void print(std::ostream &os) { os << basename; } private: std::string basename = "abc"; }; class derived : public base { public: void print(std::ostream &os) { base::print(os); os << " " << i; } private: int i = 0; };
当我在Main.cpp中不包括iostream头文件时,std::cout按预期不被识别。我的问题是:如果没有包括iostream,为什么在Quote.h中使用std::ostream没有问题?由于cout和ostream都是在前述的库中定义的,为什么使用cout会有问题,而使用ostream却没有问题?
我使用的是VS 2017,这些信息是否重要?
问题的出现原因是,C++标准只定义了头文件<string>
中使用std::ostream
的输出操作符的声明,但并没有规定这个声明是否应该在std::ostream
中普遍可用。不同的实现可能选择不将这个声明作为可用的。虽然我尝试在我的实现中只提供标准规定的声明,但这并没有像听起来那么简单。
为了解决这个问题,我们可以自己定义一个输出操作符来适应这种情况。首先,我们需要在代码中包含头文件<string>
,以便能够使用std::ostream
。然后,我们可以定义一个适用于std::ostream
的输出操作符,使其能够输出我们想要的数据类型。例如,我们可以定义一个输出操作符来输出一个自定义的类的对象:
class MyClass {
public:
int value;
};
std::ostream& operator<<(std::ostream& os, const MyClass& obj) {
os << obj.value;
return os;
}
通过这样定义一个输出操作符,我们就可以在使用std::ostream
时,输出我们自定义类的对象了。这样,即使在某些实现中没有定义std::ostream
的输出操作符,我们也能够正常使用它。
问题的出现原因是在main.cpp文件中没有直接包含
解决方法是始终保持头文件的自包含性,即在头文件中包含它所依赖的所有头文件。
如果更改#include
为了避免类似的问题,我们应该始终保持头文件的自包含性,并按照推荐的顺序组织我们的#include语句。