我是这个网站的新手,我在C ++中尝试一个简单的继承示例。 我检查了很多次代码,我发现它没有任何问题,但是编译器给了我错误:
我的代码:
#ifndef READWORDS_H
#define READWORDS_H
using namespace std;
#include "ReadWords.h"
/**
* ReadPunctWords inherits ReadWords, so MUST define the function filter.
* It chooses to override the default constructor.
*/
class ReadPunctWords: public ReadWords {
public:
bool filter(string word);
};
#endif
我从编译器得到的消息:
ReadPunctWords.h:11: error: expected class-name before '{' token
ReadPunctWords.h:13: error: `string' has not been declared
ReadPunctWords.h:13: error: ISO C++ forbids declaration of `word' with no type
Tool completed with exit code 1
我真的不确定我在哪里弄错了,因为它对我来说很好看? 感谢您发现的任何错误。
答案 0 :(得分:12)
您需要包含字符串:
#include <string>
那就是说,不要使用using namespace
!特别是在文件范围内,肯定不在头文件中。现在任何包含此文件的单元都被迫屈服于std
命名空间中的所有内容。
拿出来,并确定你的名字:
bool filter(std::string word);
它的可读性也更具可读性。另外,您应该将字符串作为const&
:
bool filter(const std::string& word);
避免不必要地复制字符串。最后,你的头部护卫似乎关闭了。他们应该改变吗?截至目前,它们看起来与您的其他标题中使用的相同,可能会有效阻止它被包含在内。
如果您定义READWORDS_H
然后包含ReadWords.h
,如果还有:{/ p>
#ifndef READWORDS_H
#define READWORDS_H
然后将处理该文件中的任何内容。如果是这种情况,则不会定义ReadWords
作为类,并且您不能继承它。你的警卫应该是:
READPUNCTWORDS_H
答案 1 :(得分:2)
您需要包含<string>
并指定命名空间:
#include <string>
using namespace std;
此外,您的包含警卫应该命名为READPUNCHTWORDS_H
,而不是READWORDS_H
。
编辑:第二个想法,GMan关于不将using namespace
放在头文件中是正确的 - 改为使用std::string
限定字符串。
答案 2 :(得分:1)
这种特殊形式的错误通常是由未定义的类型引起的(至少当代码看起来语法正确时),在这种情况下可能是类ReadWords但也可能是std :: string。
你需要包括获取std :: string,正如其他海报所写,但也需要你的后卫
#ifndef READWORDS_H
#define READWORDS_H
几乎可以肯定与ReadWords.h中的守卫发生冲突。你需要确保你的警卫在不同的头文件中是不同的,否则你会遇到这样的冲突。你应该把守卫改成像
这样的东西#ifndef READPUNCTWORDS_H
#define READPUNCTWORDS_H
// ...
#endif
事实上,拥有更加冗长的警卫以确保它们不会发生冲突会更好。我们使用格式
的守卫#ifndef MODULE_OR_PATH_FILE_H_INCLUDED
#define MODULE_OR_PATH_FILE_H_INCLUDED
// ...
#endif
这确保了具有相似命名标题的不同模块或库不会发生冲突,最后包含的内容是我自己特定的缺陷,使得警卫更具可读性。
在头文件中放置“using”声明也是不好的做法,因为它会在包含标题的任何位置放置全局命名空间中的(可能不需要的或冲突的)符号。就个人而言,我更喜欢保留命名空间以保持清晰度,或者如果它很长,我更喜欢将其命名为cpp文件,例如
namespace fs = boost::filesystem;
答案 3 :(得分:0)
看起来像ReadWords类def(第11行的消息)有问题 - 我们需要看到.h文件
aha - 你使用的sentinial def会阻止readwords.h包括被读取
你需要
#ifndef _READPUNCTWORDS_H
#define _READPUNCTWORDS_H
答案 4 :(得分:0)
我也怀疑包括警卫。如果它们在两个头文件中以相同的方式命名,则当ReadWords.h粘贴到ReadPunctWords.h时,结果应类似于以下内容。
#ifndef READWORDS_H // Is READWORDS_H defined? No, proceeding
#define READWORDS_H // Now it is defined
// Contents of ReadWords.h is pasted in here
#ifndef READWORDS_H // Is READWORDS_H defined? Yes, ignoring the contents of ReadWords.h (skipping til #endif)
#define READWORDS_H
class ReadWords { ... }; // This is never seen by the compiler as the preprocessor removed it
#endif
class ReadPunctWords: public ReadWords { // Error: ReadWords isn't declared...
public:
bool filter(string word);
};
#endif