2013-05-14 89 views
6

我需要实现一个数字类,支持运算符< <输出。 我有一个错误:“标识符‘ostream的一些原因eventhough我列入’未定义”,并尝试也标识符“ostream”未定义错误

这里的头文件:

Number.h

#ifndef NUMBER_H 
#define NUMBER_H 
#include <iostream> 
class Number{ 
public: 
//an output method (for all type inheritance from number): 
virtual void show()=0; 

//an output operator: 
friend ostream& operator << (ostream &os, const Number &f); 


}; 

#endif 

为什么心不是编译识别朋友功能中的ostream?

+0

因为与所有标准库类型和函数一样,只有*没有*'ostream'。只有'std :: ostream'。 – 2013-05-14 11:42:33

回答

11

您需要与类生活在命名空间的名称完全限定名ostream

std::ostream 
// ^^^^^ 

所以,你的运营商的声明应该成为:

friend std::ostream& operator << (std::ostream &os, const Number &f); 
//  ^^^^^      ^^^^^ 

或者,你可以有一个using声明前出现不合格名称ostream出现:

using std::ostream; 

这会允许您在没有完全限定的情况下编写ostream名称,就像您当前版本的程序一样。

+0

非常感谢!可能使用命名空间std;将工作吗? – 2013-05-14 11:11:44

+3

虽然不应该在标题的全局名称空间中使用'',因为这可能会导致标题其他用户的名称冲突。 – 2013-05-14 11:12:12

+1

@AviadChmelnik:它会起作用,但正如Mike Seymour指出的那样,它被认为是一种糟糕的编程习惯,因为引入名称冲突的可能性很高(特别是当放在全局名称空间范围的头部时)。相反,如果可以,请选择 – 2013-05-14 11:14:18

0

Andy Prowl的答案很好,但请不要在标题中加入“using std :: ostream”。如果你这样做了,那么其他编译单元使用你的头文件也会默认使用这个名字空间,并且你可以通过命名空间冲突得到令人讨厌的编译错误。

+2

'使用std :: ostream'将一个名称放入使用它的命名空间:'ostream'。这远不像使用名字空间标准符号这样大的问题,它将每个**名字从'std'放入该名字空间。 – 2013-05-14 11:18:25

+1

其他编译单元只会获得'ostream'名称,而不是名称空间。不过,我同意这是一个坏主意。 – juanchopanza 2013-05-14 11:19:05

相关问题