我有这个C ++代码。
#include <string>
#define IC(E) virtual const E const = NULL;
struct IDumpable
{
IC(std::string ToDumpString());
};
class Hello : public IDumpable
{
public:
const std::string ToDumpString() const {
std::string a("hello"); return a;
}
};
int main()
{
Hello hello;
hello.ToDumpString();
}
它使用MSVC编译/运行良好,但是g ++出现invalid pure specifier (only '= 0' is allowed) before ‘;’ token
错误。
它出了什么问题?
答案 0 :(得分:3)
GCC对__null
使用内置NULL
(这是一个常数整数表达式,评估为零.GCC上的__null
满足此要求),以便它可以检测特殊情况和警告他们。比如,意外地将NULL
传递给bool
参数,当它打算传递给指针参数时(对函数进行更改,忘记调整调用端)。
就像错误消息所说的那样,使虚拟函数纯粹需要精确的令牌序列= 0
,而不是其他一些东西(= 0L
或其他东西也会失败)。
答案 1 :(得分:3)
NULL是一个宏,g ++很可能定义为其他而不是文字零,这是完全允许的。明确使用= 0
来声明抽象函数。
另外,我真的建议不要使用宏,例如你必须声明这样的纯函数。如果他们为了理解声明而必须查看其意义,那么这将使未来的维护者不那么清楚。
答案 2 :(得分:2)
你在哪里得到了在纯粹的说明符中使用NULL
宏的奇怪习惯?
在纯说明符中使用NULL
将不起作用。纯说明符的语法是= 0
,只有= 0
,没有别的。如果它之前适用于您,则只是意味着您之前使用的编译器将NULL
宏定义为普通0
。因此,纯粹巧合的是,当使用该编译器时,您可以使用= NULL
作为纯指示符。
但一般情况下NULL
未定义为普通0
,正如我上面所述,= NULL
没有任何意义,因为纯粹的说明符。不起作用。这正是你在案件中所观察到的。
答案 3 :(得分:2)
错误消息的确切含义是什么:纯虚函数规范中允许仅"= 0"
,而您改为= NULL
。 C ++标准将NULL
定义为“实现定义的C ++空指针常量”(C ++03§18.1/ 4)。 0是一个这样的空指针常量,但NULL
不需要为0.
恰好MSVC将NULL
定义为0,但GCC实际上将NULL
定义为__null
。 GCC说__null
是一个有效的空指针常量,但是__null
不是0,所以你不能在纯虚函数的规范中使用它。