問題タブ [virtual-functions]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 仮想関数の呼び出しが失敗するのはなぜですか?
更新:この問題は、メモリの使用率が低いために発生します。下部の解決策を参照してください。
ここにいくつかの半疑似コードがあります:
C# に相当するものは次のとおりです。C# の例は、実際の問題とは関係がないため削除されました。
ClassB::VirtualFunction
から呼び出されたときに関数が呼び出されないのはなぜClassA::SomeFunction
ですか? 代わりClassA::VirtualFunction
に呼び出されています...
仮想関数 ClassA::VirtualFunction の実装を強制すると、次のようになります。
派生関数が確実に宣言および定義されているにもかかわらず、実行時に次のエラーが発生します。
注:メモリ使用量が悪い場合でも、エラーが発生する可能性があるようです。詳細については、自己回答を参照してください。
更新 1 - 4:
コメントは削除されました (関係ありません)。
解決:
c# - C# がデフォルトでメソッドを非仮想として実装するのはなぜですか?
Java とは異なり、C# がデフォルトでメソッドを非仮想関数として扱うのはなぜですか? 考えられる他の結果よりも、パフォーマンスの問題である可能性が高いですか?
既存のアーキテクチャがもたらすいくつかの利点について、Anders Hejlsberg の段落を読んだことを思い出しました。しかし、副作用はどうですか?デフォルトで非仮想メソッドを持つことは本当に良いトレードオフですか?
java - すべての Java メソッドが暗黙的にオーバーライド可能であるのはなぜですか?
C++ では、メンバー関数をオーバーライド可能にするには、'virtual' キーワードを明示的に指定する必要があります。これは、メンバー関数がオーバーライド可能になると、仮想テーブルと vpointer を作成するオーバーヘッドが発生するためです (したがって、すべてのメンバー関数は暗黙的にオーバーライド可能ではありません)。パフォーマンス上の理由)。
また、サブクラスが同じ名前とシグネチャを持つ別の実装を提供する場合、メンバー関数を非表示にすることもできます (オーバーライドされていない場合)。
C# でも同じ手法が使用されています。なぜ Java がこの動作から離れて、デフォルトですべてのメソッドをオーバーライド可能にし、「final」キーワードを明示的に使用したときにオーバーライド動作を無効にする機能を提供したのか疑問に思っています。
c++ - コンストラクター内での仮想関数の呼び出し
2 つの C++ クラスがあるとします。
次のコードを書くと:
2に設定されていると予想されるかもしれませんn
。
が 1 に設定されていることn
がわかりました。なぜでしょうか。
c++ - 仮想割り当てが同じ署名の他の仮想関数とは異なる動作をするのはなぜですか?
仮想代入演算子の実装で遊んでいる間、私はおかしな振る舞いで終わりました。g ++ 4.1、4.3、およびVS 2005は同じ動作を共有するため、これはコンパイラの不具合ではありません。
基本的に、virtual operator =は、実際に実行されているコードに関して、他の仮想関数とは異なる動作をします。
その結果、仮想演算子=は、実際の派生オブジェクト([1])を介して呼び出されたときに演算子のベースバージョンを呼び出すことにより、同じシグネチャを持つ他の仮想関数とは異なる動作をします([1]と比較して[0])。 )または派生参照([3])は、ベース参照([2])を介して呼び出された場合、または左辺値または右辺値のいずれかがベース参照であり、他の派生参照([4]、 [5])。
この奇妙な振る舞いに対する賢明な説明はありますか?
c++ - 仮想関数を使用しないコマンドパターン(C ++)
パフォーマンス上の理由から、仮想関数を回避するために、不思議なことに繰り返し発生するテンプレートパターンを使用しています。何百万回も実行する小さなコマンドがたくさんあります。これをコマンドパターンに適合させようとしています。キューに大量のコマンドを追加してから、それらを繰り返し実行して、それぞれを1つずつ実行したいと思います。各コマンドは、仮想機能を回避するためにCRTPを使用します。私が遭遇している問題は、コマンドパターンが通常ポインターのベクトルを使用して実装されていることです。ただし、Commandクラスがテンプレート化されている場合、汎用Commandポインターを渡すのは困難になります。私はC++の専門家ではないので、テンプレート化されたコマンドオブジェクトのベクトルを格納する明白な方法があるのではないでしょうか。私は次のようなものを使おうとしています:
問題はCommand
型ではないためCommand* command
、コンパイルエラーが発生します。を使用するCommand<CommandType>
必要がありますが、さまざまな種類のコマンドを保持するためのキューが必要なため、それは機能しません。
ソリューションのアイデアはありますか?それとも、仮想関数は私の唯一の選択肢ですか?
追加:コマンドオブジェクトは、モンテカルロシミュレーションアルゴリズムの一部です。つまり、Commandは正規分布からの乱数であり、正規分布のパラメーターはクラスの一部です。したがって、コマンドパターンは非常にうまく適合します。状態を維持する必要のある関数に対して、特定の順序で多くの呼び出しがあります。
c++ - C++ で派生したパブリック仮想関数プライベート
派生クラスが仮想関数をプライベートとして宣言するとどうなるかを理解しようとしていました。以下は私が書いたプログラムです
驚いたことに(私にとって)出力は次のとおりです。
これは、その機能のプライベート アクセス セットに違反していませんか。これは予想される動作ですか?これは標準的な回避策ですか、それとも抜け穴ですか? VTABLE を介して関数呼び出しを解決するときに、アクセス レベルはバイパスされますか?
この動作に関する洞察は非常に役立ちます。
さらに、仮想メンバーを非公開でオーバーライドすると、それ以上のクラスがそれを継承できなくなることが言及されました。これでも問題があります。上記のプログラムを次のように変更します。
そしてメインのテストプログラムは次のことを行います:
出力は次のとおりです。
c# - C# での仮想関数の実用的な使用法
c# での仮想関数の実際の使用法は何ですか?
c++ - C ++での純粋仮想関数の用途は何ですか?
私は今、クラスでC ++について学んでいますが、純粋仮想関数についてはあまり理解していません。後で派生クラスで概説されることを理解していますが、派生クラスで定義するだけの場合、なぜ0に等しいと宣言したいのでしょうか。