C++で「抽象クラスをインスタンス化できない」エラーをどのように処理しますか?私はここで同様のエラーのいくつかを見てきましたが、それらのどれも私が持っているものとまったく同じでも問題でもないようです。しかし、再び、私はいくつかの問題があることを認めます。コンパイルエラーは次のとおりです。
これは私をこのページに導きます: http://msdn.Microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C2259); k(VS.ERRORLIST)&rd = true コンパイルエラーC2259はC++プログラムからのものですが、ページは抽象クラスを「インターフェイス」と呼びます。
インターフェイスから派生し、パブリック以外のアクセス許可を持つ派生クラスでインターフェイスメソッドを実装するたびに、C2259を受け取る場合があります。これは、派生クラスに実装されたインターフェイスメソッドがパブリックアクセスを持っていることをコンパイラが予期しているために発生します。より制限されたアクセス許可を持つインターフェイスのメンバー関数を実装すると、コンパイラはそれらをインターフェイスで定義されたインターフェイスメソッドの実装と見なしません。これにより、派生クラスが抽象クラスになります。
この問題には、次の2つの回避策があります。
実装されたメソッドのアクセス許可を公開します。
派生クラスに実装されたインターフェイスメソッドのスコープ解決演算子を使用して、実装されたメソッド名をインターフェイスの名前で修飾します。
悪いニュースは、クラスですべてのメソッドを既に公開していることです:
class AmbientOccluder: public Light {
public:
AmbientOccluder(void);
エラーは、実装されていないクラスのメソッドがあることを意味します。そのようなクラスをインスタンス化することはできないため、クラスのメソッドのallを実装する以外にできることは何もありません。
一方、一般的なパターンは、具象クラスをインスタンス化し、それを抽象基本クラスのポインターに割り当てることです。
class Abstract { /* stuff */ 4};
class Derived : virtual public Abstract { /* implement Abstract's methods */ };
Abstract* pAbs = new Derived; // OK
余談ですが、上記の行でのメモリ管理の問題を回避するために、 `std :: unique_ptrなどの スマートポインター の使用を検討できます。
std::unique_ptr<Abstract> pAbs(new Derived);
Visual Studio エラーリストペインには、エラーの最初の行のみが表示されます。 View
> Output
を呼び出すと、次のようなものが表示されるはずです。
c:\path\to\your\code.cpp(42): error C2259: 'AmbientOccluder' : cannot instantiate abstract class
due to following members:
'ULONG MysteryUnimplementedMethod(void)' : is abstract
c:\path\to\some\include.h(8) : see declaration of 'MysteryUnimplementedMethod'
抽象クラスは、定義によりインスタンス化できません。このクラスを使用するには、クラスのすべての仮想機能を実装する具象サブクラスを作成する必要があります。この場合、Light
で宣言されたすべての仮想関数を実装していない可能性があります。つまり、AmbientOccluder
はデフォルトで抽象クラスになります。さらに支援するために、Light
クラスの詳細を含める必要があります。
クラスが持っている純粋な仮想関数の実装を提供します。
なぜ抽象クラスのオブジェクトを作成できないのですか? Abstractクラスで純粋な仮想関数を作成するとき、VTABLEの関数用のスロットを予約します(最後のトピックで検討しました)が、そのスロットにはアドレスを入れません。したがって、VTABLEは不完全になります。 AbstractクラスのVTABLEは不完全であるため、コンパイラはそのようなクラスのオブジェクトの作成を許可せず、実行しようとするとエラーメッセージを表示します。
純粋仮想定義
Pure Virtual関数には、Abstractクラスで小さな定義を与えることができます。これには、すべての派生クラスが必要です。それでも、Abstractクラスのオブジェクトを作成することはできません。また、Pure Virtual関数はクラス定義の外部で定義する必要があります。クラス定義内で定義すると、コンパイラーはエラーを返します。インライン純粋仮想定義は違法です。
私の場合、COM Control .idl
ファイルのような
[id(1)] HRESULT MyMethod([in]INT param);
しかし、私のインターフェースで宣言されていません.h
このようなファイル
STDMETHOD(MyMethod)(INT param);
上記の行をインターフェイスの.hファイルに追加することで解決した問題
これはある人を助けるかもしれません。
ここでこの質問に答えました。 共変仮想関数は型の問題を返します
何らかの助けになるかどうかを確認してください。