問題タブ [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++ - 仮想関数オーバーライド時の例外指定
次のコードを検討してください。
コンパイルすると、派生クラス B は A に比べてスロー指定子が緩いことが示されます。これの重要性は何ですか? A::f() が int と double をスローし、B::f() が int のみをスローするように例外仕様を交換しようとすると、エラーは表示されません。
c++ - なぜ C++ で仮想関数が必要なのですか?
私は C++ を学んでいて、仮想関数を始めたところです。
(本とオンラインで) 私が読んだことから、仮想関数は、派生クラスでオーバーライドできる基本クラスの関数です。
しかし、この本の前半で、基本的な継承について学習したときに、派生クラスの基底関数を .xml を使用せずにオーバーライドすることができましたvirtual
。
それで、私はここで何が欠けていますか?仮想関数には他にもあることを知っており、それが重要であるように思われるので、それが正確に何であるかを明確にしたいと思います。私はオンラインで簡単な答えを見つけることができません。
c++ - 仮想クラスのセグメンテーション違反
私はグラフィックアプリケーションに取り組んでいます。仮想クラスを大幅に活用します。デバッグに問題があるセグメンテーション違反が発生しています。
このアプリケーションの主要なクラスは次のとおりです。
- Shape (仮想クラス)
- 矩形
- ポリゴン
- サークル
- 画像 (基本的には図形のコレクション)
私のコードの該当部分の短縮コピーは次のとおりです。
以下は、いくつかの情報を示す gdb セッションです。
私はこのことを理解しようとして、数時間壁に頭をぶつけていました。これは、Picture クラスの Graphic メンバーと関係があります。ただし、それがどのように組み合わされてセグメンテーション違反が発生するかはわかりません。
編集:
これは、Graphics オブジェクトが作成される testpicture.cpp の部分です。
グラフィックも仮想クラスです。この場合、PSGraphic はそれを継承します。
.net - C++ 対 C++/CLI: 仮想関数パラメーターの const 修飾
[以下はすべて、Visual Studio 2008 SP1 を使用してテストされています]
C++ では、パラメーター型の const 修飾は関数の型に影響しません (8.3.5/3: 「パラメーター型を変更する cv-qualifier は削除されます」)。
したがって、たとえば、次のクラス階層では、Derived::Foo
overrides Base::Foo
:
C++/CLI で同様の階層を考えてみましょう。
次に、のインスタンスを作成するとDerived
:
エラーや警告なしでコンパイルされます。実行すると、次の例外がスローされて終了します。
タイプ 'System.TypeLoadException' の未処理の例外が ClrVirtualTest.exe で発生しました
追加情報: タイプ 'Derived' のメソッド 'Foo' ... には実装がありません。
その例外は、パラメーターの const 修飾がC ++/CLI の関数の型に影響を与える (または、少なくとも何らかの方法でオーバーライドに影響を与える) ことを示しているようです。ただし、 の定義を含む行をコメント アウトするとDerived::Foo
、コンパイラは次のエラーを報告します (main
のインスタンスDerived
がインスタンス化されている行で)。
エラー C2259: 'Derived': 抽象クラスをインスタンス化できません
のパラメーターに const 修飾子を追加するDerived::Foo
か、のパラメーターから const 修飾子を削除するBase::Foo
と、エラーなしでコンパイルおよび実行されます。
パラメーターの const 修飾が関数の型に影響を与える場合、派生クラスの仮想関数のパラメーターの const 修飾が基本クラスの virtual のパラメーターの const 修飾と一致しない場合、このエラーが発生するはずだと思います関数。
Derived::Foo
のパラメータの型をanint
から aに変更するdouble
と、(前述のエラー C2259 に加えて) 次の警告が表示されます。
警告 C4490: 'override': オーバーライド指定子の使用が正しくありません。'Derived::Foo' は基本参照クラス メソッドと一致しません
したがって、私の質問は、事実上、関数パラメーターの const 修飾が C++/CLI の関数の型に影響するかどうかです。もしそうなら、なぜこれはコンパイルされ、エラーや警告がないのはなぜですか? そうでない場合、なぜ例外がスローされるのですか?
c++ - 仮想関数の問題
VSTS2008でネイティブC++を使用しています。仮想関数に関する簡単な質問です。以下の私のサンプルでは、FooをDerivedクラスで「virtualvoidFoo()」または「voidFoo()」として宣言した場合の違いはありますか?クラス派生から派生する将来のクラスへの影響はありますか?
c++ - 良いスタイルで仮想関数をオーバーライドするには? 【C++】
私はこの質問が非常に基本的であることを知っていますが、いくつかの出版物(Webサイト、本)で異なるスタイルのオーバーライド仮想関数に会いました。つまり、基本クラスがある場合:
一部の出版物では、これを無効にするために、一部の著者が次のように言うだけであることがわかりました。
また、void の前に virtual キーワードを繰り返すものもあります。どの形式の上書きが適切ですか? 回答ありがとうございます。
c++ - 「= 0」で終わる C++ ヘッダー ファイルと関数宣言
.h ファイル内に次のコードがありますが、代入ステートメントが何を行い、どのように適切に呼び出されるのかわかりません。
この関数はデフォルトで値 0 を返すと思っていましたが、この関数は void を返すため、少し混乱しています。誰かがこれについてコメントして、この割り当てをどのように参照できるかを言うことができますか?つまり、C++ 専門用語でどのように呼び出されるのでしょうか?
ありがとう。
c++ - ベースクラスポインタC++からのサブクラスメンバーへのアクセス
カスタムクラスのStudentオブジェクトの配列があります。CourseStudentとResearchStudentはどちらもStudentを継承しており、Studentのすべてのインスタンスはこれらのいずれかです。
配列を調べて、各Studentのサブタイプを判別し、それらに対してサブタイプ固有のメンバー関数を呼び出す関数があります。
問題は、これらの関数がオーバーロードされていないため、Studentで見つからないため、コンパイラーが大騒ぎすることです。
Studentへのポインターがある場合、そのStudentのサブタイプへのポインターを取得する方法はありますか?コンパイル時のエラーを回避するために、ここで何らかの偽のキャストを作成する必要がありますか?
java - Javaのinvokevirtualが呼び出されたメソッドのコンパイル時クラスを解決する必要があるのはなぜですか?
この単純なJavaクラスについて考えてみます。
c.foo()行で何が起こるかについて説明したいと思います。
元の誤解を招く質問
注:これのすべてが実際に個々のinvokevirtualオペコードで発生するわけではありません。ヒント:Javaメソッドの呼び出しを理解したい場合は、invokevirtualのドキュメントだけを読んではいけません。
バイトコードレベルでは、c.foo()の要点はinvokevirtualオペコードになり、invokevirtualのドキュメントによると、多かれ少なかれ次のことが起こります。
- コンパイル時クラスMyClassで定義されているfooメソッドを検索します。(これには、最初にMyClassを解決することが含まれます。)
- 次のようないくつかのチェックを行います。cが初期化メソッドではないことを確認し、MyClass.fooの呼び出しが保護された修飾子に違反しないことを確認します。
- 実際に呼び出すメソッドを見つけます。特に、cのランタイムタイプを検索します。そのタイプにfoo()がある場合は、そのメソッドを呼び出して戻ります。そうでない場合は、cのランタイムタイプのスーパークラスを検索します。そのタイプにfooがある場合は、そのメソッドを呼び出して戻ります。そうでない場合は、cの実行時型のスーパークラスのスーパークラスを検索します。そのタイプにfooがある場合は、そのメソッドを呼び出して戻ります。など。適切な方法が見つからない場合は、エラーが発生します。
ステップ3だけで、呼び出すメソッドを見つけ出し、そのメソッドが正しい引数/戻り型を持っていることを確認するのに十分なようです。だから私の質問は、なぜステップ#1が最初に実行されるのかということです。考えられる答えは次のようです。
- ステップ1が完了するまで、ステップ3を実行するための十分な情報がありません。(これは一見信じられないようですので、説明してください。)
- #1と#2で行われるリンクまたはアクセス修飾子のチェックは、特定の悪いことが起こらないようにするために不可欠であり、これらのチェックは、実行時型階層ではなく、コンパイル時型に基づいて実行する必要があります。(説明してください。)
改訂された質問
行c.foo()のjavacコンパイラ出力のコアは、次のような命令になります。
ここで、iはMyClassのランタイム定数プールへのインデックスです。その定数プールエントリは、タイプCONSTANT_Methodref_infoであり、(おそらく間接的に)A)呼び出されるメソッドの名前(つまり、foo)、B)メソッドのシグネチャ、およびC)メソッドが呼び出されるコンパイル時クラスの名前を示します。 on(つまり、MyClass)。
問題は、なぜコンパイル時型(MyClass)への参照が必要なのかということです。invokevirtualは実行時型cで動的ディスパッチを実行するので、コンパイル時クラスへの参照を格納するのは冗長ではありませんか?
c++ - 本体を使用した純粋仮想関数のユースケース?
私は最近、C++ では純粋仮想関数が必要に応じて本体を持つことができることを知りました。
そのような機能の実際の使用例は何ですか?