2

“不纯虚函数”是指纯虚函数,它们也具有用于诊断目的的实现(如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"

...

以便它获得单个编译的实现。

这样做会合法吗?

4

2 回答 2

4

不,这不合法。一个定义规则说一个类可以在程序中有多个定义(来自不同的翻译单元),但这些定义必须全部由相同的标记序列组成(3.2/5)。ABSTRACT_METHOD是一个预处理标记(在宏替换之前),但这还不够好。

因此,您的 .cpp 文件不能与包含标头的另一个 .cpp 有效地在同一程序中使用。

于 2010-11-20T20:34:23.870 回答
0

我无法回答它是否有效。但是如果你的类的用户在源文件中声明了一个派生类,编译器将不会强制Bar()必须在该派生类中实现(因为它不会看到= 0)。我想这本身就是不这样做的理由。

于 2010-11-20T20:27:35.283 回答