我在base.h文件中有一个基类
#ifdef _BASE_H_
#define _BASE_H_
class base {
public:
int base_data;
};
#endif
和派生类
#include "base.h"
class derived: public base {
public:
int derived1_data;
inline void set(int data) { derived1_data = data;}
};
当我尝试编译时,我收到此错误:
error: expected class-name before ‘{’ token
我不确定我在这里做错了什么。
答案 0 :(得分:4)
#ifdef _BASE_H_
应为#ifndef _BASE_H_
。
或者只使用#pragma once
:)
答案 1 :(得分:3)
更改
#ifdef _BASE_H_
到
#ifndef _BASE_H_
答案 2 :(得分:2)
标题中的更改
#ifdef _BASE_H_
到
#ifndef _BASE_H_
答案 3 :(得分:2)
问题出在头文件#ifdef _BASE_H_
的第一行。它应该是#ifndef _BASE_H_
(注意额外的'n')
以下是对正在发生的事情的简要说明:
#ifdef MACRO_NAME
<line 1>
<line 2>
...
#endif
此代码告诉C ++预处理器在源代码中仅包含 line1 , line2 ,...如果先前已定义宏MACRO_NAME
到目前为止(注意:重要的只是宏的定义,而不是它的价值。如果你想在宏值上预测代码包含,你可以使用#if
)
您在此处尝试使用的技术称为Include Guard,它可以防止重复包含代码(主要通过#include
预处理程序指令)。这个想法包括头文件的源代码只有某些宏(比如说“M”)还没有定义,然后在头文件代码中你要做的第一件事是定义那个宏“ M“(以便下次调用#include samefile
将不再包含其代码)。要创建包含保护,您需要使用#ifndef
预处理器指令(与#ifdef
完全相反,实际上,额外的 n 代表“NOT”)。
由于您错误地使用了#ifdef
,因此永远不会包含文件base.h
(因为在确定宏_BASE_H_
已经定义之后,唯一定义宏base
的地方!)。因此编译器不知道类expected class-name before ‘{’ token
,导致错误{{1}}
答案 4 :(得分:1)
尽管宏的名称不应该以下划线开头,但你在“标题保护”中有错误
#ifdef _BASE_H_
如果宏已经定义,这只会编译到#endif
的内容,这与您想要做的相反。这就是你应该写
#ifndef _BASE_H_
如果已经定义了宏,那么基本上忽略忽略<{1>}的内容,如果文件已经已包含在内,则情况就是这样。
但是你的编译器无法检测到这是真正的问题。相反,它默默地忽略头文件#endif
的内容,这意味着永远不会定义基类(它将找不到源代码!)。所以到达线时
base.h
编译器不知道类型class derived : public base {
,这意味着您无法从中派生,因此会出现类名称所期望的错误消息。