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

いいえ、それは合法ではありません。1つの定義規則では、クラスはプログラム内に(異なる変換単位からの)複数の定義を持つことができますが、それらの定義はすべて、トークンの同一のシーケンス(3.2 / 5)で構成されている必要があります。ABSTRACT_METHODは前処理トークン(マクロ置換前)ですが、それだけでは十分ではありません。

そのため、.cppファイルを、ヘッダーを含む別の.cppと同じプログラムで有効に使用することはできません。

于 2010-11-20T20:34:23.870 に答える
0

有効かどうかは答えられません。ただし、クラスのユーザーがソースファイルで派生クラスを宣言した場合、コンパイラはBar()その派生クラスに実装する必要があることを強制しません(が表示されないため= 0)。これだけでこうしない理由になると思います。

于 2010-11-20T20:27:35.283 に答える