通过“不纯的虚函数”,我的意思是纯虚函数也有实现(如http://www.gotw.ca/gotw/031.htm所述)用于诊断目的。
实施它们的犹太方法是:
class Foo
{
public:
...
virtual void Bar() = 0;
};
void Foo::Bar() { assert(false); }
但是这有点单调乏味,特别是对于一个类有一些纯虚方法。此外,如果没有添加相应的实现,很难确保有人不会意外添加新的纯虚函数。
理想情况下,我想做的是:
class Foo
{
public:
...
virtual void Bar() = 0
{
assert(false);
}
};
但C ++标准明确禁止这一点(ISO C ++ 2003标准中的第10.4/2节)。
作为替代方案,我想到了以下黑客攻击。在Foo.h
标题中:
#ifndef ABSTRACT_METHOD
#define ABSTRACT_METHOD = 0
#endif
class Foo
{
public:
...
virtual void Bar() ABSTRACT_METHOD;
};
然后在相应的Foo.cpp
源文件中:
#define ABSTRACT_METHOD { assert(false); }
#include "Foo.h"
...
以便它获得单个编译实现。
这样做会合法吗?
答案 0 :(得分:4)
不,这不合法。一个定义规则说一个类可以在一个程序中有多个定义(来自不同的翻译单元),但这些定义必须都包含相同的标记序列(3.2 / 5)。 ABSTRACT_METHOD
是一个预处理令牌(在宏替换之前),但这还不够好。
因此,您的.cpp文件无法在与包含标题的另一个.cpp相同的程序中有效使用。
答案 1 :(得分:0)
我无法回答它是否有效。但是,如果您的类的用户在源文件中声明派生类,则编译器不会强制必须在该派生类中实现Bar()
(因为它不会看到= 0
)。我想,仅此一点就不是这样做的理由。