这是实现不纯虚函数的合法方法吗?
我所说的“不纯虚函数”是指也有实现的纯虚函数(如 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"
...
以便获得单个已编译的实现。
这样做合法吗?
By an "impure virtual function", I mean pure virtual functions that also have implementations (as described at http://www.gotw.ca/gotw/031.htm) for diagnostic purposes.
The kosher way to implement them is to do:
class Foo
{
public:
...
virtual void Bar() = 0;
};
void Foo::Bar() { assert(false); }
But this is kind of tedious, especially for a class has a number of pure virtual methods. Also, it's hard to ensure that someone doesn't accidentally add a new pure virtual function without also adding a corresponding implementation.
Ideally what I'd like to do is:
class Foo
{
public:
...
virtual void Bar() = 0
{
assert(false);
}
};
but the C++ standard explicitly disallows this (section 10.4/2 in the ISO C++ 2003 standard).
As an alternative, I've thought of the following hack. In the Foo.h
header:
#ifndef ABSTRACT_METHOD
#define ABSTRACT_METHOD = 0
#endif
class Foo
{
public:
...
virtual void Bar() ABSTRACT_METHOD;
};
and then in the corresponding Foo.cpp
source file:
#define ABSTRACT_METHOD { assert(false); }
#include "Foo.h"
...
so that it gets a single compiled implementation.
Would doing so be legal?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,这是不合法的。单一定义规则规定,一个类可以在程序中具有多个定义(来自不同的翻译单元),但这些定义必须全部由相同的标记序列组成 (3.2/5)。
ABSTRACT_METHOD
是一个预处理标记(在宏替换之前),但这还不够好。因此,您的 .cpp 文件无法与包含标头的另一个 .cpp 文件在同一程序中有效使用。
No, it's not legal. The one definition rule says that a class can have multiple definitions in a program (from different translation units), but those definitions must all consist of identical sequences of tokens (3.2/5).
ABSTRACT_METHOD
is a preprocessing token (prior to macro replacement), but that's not good enough.So your .cpp file can't validly be used in the same program as another .cpp that includes the header.
我无法回答它是否有效。但是,如果类的用户在源文件中声明了派生类,则编译器不会强制必须在该派生类中实现
Bar()
(因为它不会看到Bar()
)。 >= 0)。我想仅此一点就可以成为不这样做的理由。I can't answer whether it's valid or not. But if the user of your class declares a derived class in the source file, the compiler won't enforce that
Bar()
must be implemented in that derived class (because it won't see the= 0
). I would imagine that this alone would be a reason not to do it like this.