34

C++で「抽象クラスをインスタンス化できません」というエラーをどのように処理しますか? ここで同様のエラーのいくつかを見てきましたが、どれもまったく同じではないか、私が抱えている問題ではないようです。しかし、繰り返しになりますが、いくつかのことを確認する必要があることを認めます。コンパイルエラーは次のとおりです。

[IMG]http://i67.photobucket.com/albums/h292/Athono/cannotinstantiateabstractclass.png[/IMG]

これにより、次のページに移動します: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C2259);k(VS.ERRORLIST)&rd=true C ++プログラムですが、ページは抽象クラスを「インターフェース」と呼んでいます:

インターフェイスから派生し、パブリック以外のアクセス許可を使用して派生クラスにインターフェイス メソッドを実装すると、C2259 が表示されることがあります。これは、派生クラスに実装されているインターフェイス メソッドがパブリック アクセスを持つことをコンパイラが想定しているために発生します。より制限的なアクセス許可を持つインターフェイスのメンバー関数を実装すると、コンパイラはそれらをインターフェイスで定義されたインターフェイス メソッドの実装とは見なさないため、派生クラスは抽象クラスになります。

この問題には、次の 2 つの回避策があります。

実装したメソッドのアクセス権を公開します。

派生クラスに実装されているインターフェイス メソッドのスコープ解決演算子を使用して、実装されているメソッド名をインターフェイスの名前で修飾します。

悪いニュースは、クラスですべてのメソッドを既に公開していることです。

class AmbientOccluder: public Light {
    public:

        AmbientOccluder(void); 
4

8 に答える 8

49

このエラーは、実装されていないクラスのメソッドがいくつかあることを意味します。そのようなクラスをインスタンス化することはできないため、クラスのすべてのメソッドを実装する以外にできることはありません。

一方、一般的なパターンは、具体的なクラスをインスタンス化し、それを抽象基本クラスのポインターに割り当てることです。

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);
于 2012-08-06T18:36:43.553 に答える
38

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'
于 2013-06-26T02:14:52.860 に答える
11

定義上、抽象クラスをインスタンス化することはできません。このクラスを使用するには、クラスのすべての仮想関数を実装する具体的なサブクラスを作成する必要があります。この場合、 で宣言されているすべての仮想関数を実装していない可能性がありますLight。これは、AmbientOccluderデフォルトで抽象クラスになることを意味します。私たちがさらにあなたを助けるために、あなたはLightクラスの詳細を含める必要があります.

于 2012-08-06T18:39:05.550 に答える
4

クラスが持つすべての純粋仮想関数の実装を提供します。

于 2012-08-06T18:39:28.640 に答える
1

抽象クラスのオブジェクトを作成できないのはなぜですか? Abstract クラスで純粋仮想関数を作成する場合、VTABLE で関数用のスロットを予約しますが (前のトピックで調べました)、そのスロットにはアドレスを入れません。したがって、VTABLE は不完全になります。Abstract クラスの VTABLE は不完全であるため、コンパイラはそのようなクラスのオブジェクトを作成できず、作成しようとするとエラー メッセージが表示されます。

純粋仮想の定義

Pure Virtual 関数には、Abstract クラスで小さな定義を与えることができます。これは、すべての派生クラスに持たせたいものです。それでも、Abstract クラスのオブジェクトを作成することはできません。また、Pure Virtual 関数はクラス定義の外で定義する必要があります。クラス定義内で定義すると、コンパイラでエラーが発生します。インラインの純粋仮想定義は違法です。

于 2013-10-16T13:16:01.647 に答える
0

ここでこの質問に答えました.共変仮想関数の戻り値の型の問題

それが誰かに役立つかどうかを確認してください。

于 2015-01-07T06:40:09.797 に答える
0

私の場合、次の.idlようなCOMコントロールファイルで関数を宣言しました

[id(1)] HRESULT MyMethod([in]INT param);

.hしかし、このようにインターフェースファイルで宣言されていません

STDMETHOD(MyMethod)(INT param);

インターフェイス .h ファイルに上記の行を追加することで問題が解決しました

これは誰かを助けるかもしれません。

于 2015-12-28T07:49:52.267 に答える
0

関数からこのエラーが発生している場合は、代わりにパラメーターで抽象クラスへの参照を使用してみてください。

void something(Abstract bruh){
}

void something(Abstract& bruh){
}

サブクラスからであっても、抽象クラスを構築できません。抽象クラスは基本的に、他のクラスを構築するためのテンプレートであり、コンストラクタ自体はありません。これは、継承を伴うインターフェイスを行うもう 1 つの方法です。

ポリモーフィズムに関する情報はオンライン上にたくさんありますが、どれもばかげています。C++ では、複数のクラスから同時に継承できるようになっているため、抽象クラスとインターフェイスは同じです。抽象クラスが存在する理由は、Java などの一部の言語が 1 つのクラスからしか継承/拡張できないためだと思います。

抽象クラスは文字通り抽象的な概念です。それらはクラスの親ですが、私たちの頭の中だけです。それらは、正解がない質問に対する答えです。「GTAの前身は何ですか?」みたいな。「Race n' Chase がある」と言うかもしれませんが、名前が違うだけで同じゲームなので、それは正解ではありません。抽象クラスは、「そのクラスの親は何ですか」に対する答えですか? 「ああ、文字列は単なる文字配列です」、「文字配列は単なる2つのイテレータです」、「イテレータは単なるポインタです」と言うことができます。抽象クラスを使用すると、これらの愚かな答えを継承に形式化できます。

于 2020-11-28T23:59:31.910 に答える