問題タブ [pure-virtual]

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.

0 投票する
5 に答える
435 参照

c++ - 純粋でない場合、仮想メンバー関数が使用されますか?

C++03 3.2.2 ...その名前が潜在的に評価される式に現れる場合、オブジェクトまたはオーバーロードされていない関数が使用されます。純粋でない場合は、仮想メンバー関数が使用されます...

すべてのプログラムに3.2.3、そのプログラムで使用されるすべての非インライン関数またはオブジェクトの定義が 1 つだけ含まれている必要があります。診断は必要ありません。定義は、プログラム内で明示的に表示されるか、標準またはユーザー定義ライブラリーで見つけることができます。または (適切な場合) 暗黙的に定義されます (12.1、12.4、および 12.8 を参照)。インライン関数は、それが使用されるすべての翻訳単位で定義されます。

私が読んでいる行に沿って:純粋な仮想関数は使用されていません。ODR は、使用される機能にのみ適用されます。これは、次のことが合法であることを意味しませんか? 答えはノーだと思いますが、そうではありませんが、その理由はわかりません。

0 投票する
5 に答える
5877 参照

c++ - 純粋仮想関数にはインライン定義がない場合があります。なんで?

純粋仮想関数は、仮想であり、純粋指定子( = 0;)を持つメンバー関数です。

C++03 の10.4 節のパラグラフ 2は、抽象クラスとは何かを示しており、補足として、次のことを示しています。

[注: 関数宣言は、pure-specifier と定義の両方を提供することはできません — 終わりの注] [例:

—終わりの例]

この問題にあまり詳しくない人のために、純粋仮想関数は定義を持つことができますが、上記の節はそのような定義がインライン (字句的にはクラス内) に現れることを禁止していることに注意してください。(純粋仮想関数の定義の使用については、たとえば、この GotWが表示される場合があります)

現在、他のすべての種類およびタイプの関数に対して、クラス内定義を提供することが許可されています。この制限は、一見、完全に人為的で説明がつかないように見えます。考えてみれば、2回目以降はそう見えますが(笑)でも、特に理由が無ければ制限は無いと思います。

私の質問は、これらの特定の理由を知っている人はいますか? 良い推測も大歓迎です。

ノート:

  • MSVC では、PVF にインライン定義を含めることができます。だから驚かないでください:)
  • この質問の単語は、インラインキーワードinlineを参照していません。語彙的にクラス内を意味するはずです
0 投票する
2 に答える
2284 参照

c++ - テンプレート内で純粋仮想関数を使用してC++コードをビルドしようとすると、リンカーエラーが発生するのはなぜですか?

現在作成しているアプリケーションでは、純粋仮想関数を使用してテンプレートクラスを作成し、次に前者のインスタンスを継承して仮想関数を実装する別のクラスを作成しました。仮想関数は、子によっても使用される親のコンストラクターから呼び出されます。リンカーエラーのためにこのコードをビルドできず、その理由がわかりません。これが私が抱えている問題を再現するためのコードの簡略版です。

リンカエラーは、MSVCでは次のように表示されます。

purevirttest.obj:エラーLNK2019:未解決の外部シンボル "protected:virtual void __thiscall Foo :: echo(void)"(?echo @?$ Foo @ H @@ MAEXXZ)関数 "public:__thiscall Foo :: Foo(int )"(?? 0?$ Foo @ H @@ QAE @ H @ Z)

Fooのコンストラクターからecho()の呼び出しを移動すると、コードが適切にビルドおよび実行され、bar.echo()を問題なく呼び出すことができます。問題は、コンストラクターでその関数が本当に欲しいということです。この謎の説明は大歓迎です。

0 投票する
2 に答える
663 参照

c++ - これは不純な仮想関数を実装する合法的な方法ですか?

「不純な仮想関数」とは、診断目的で ( http://www.gotw.ca/gotw/031.htmで説明されているように) 実装も持つ純粋な仮想関数を意味します。

それらを実装するコーシャの方法は次のとおりです。

しかし、これはちょっと面倒です。特に、クラスに多数の純粋仮想メソッドがある場合はそうです。また、対応する実装も追加せずに、誰かが誤って新しい純粋仮想関数を追加しないようにすることは困難です。

理想的には、私がやりたいことは次のとおりです。

しかし、C++ 標準ではこれを明示的に禁止しています (ISO C++ 2003 標準のセクション 10.4/2)。

別の方法として、次のハックを考えました。Foo.hヘッダー内:

次に、対応するFoo.cppソース ファイルで次のように指定します。

コンパイルされた単一の実装を取得するようにします。

そうすることは合法でしょうか?

0 投票する
5 に答える
1187 参照

c++ - C++ の抽象クラス メカニズムの特別な点は何ですか?

数日間気になる質問があります。

抽象クラスは、インスタンス化できない特別なタイプのクラスですよね?. (これは、少なくとも 1 つのメソッド宣言に「= 0」を与えることによって示され、指定されますが、これは後付けのように見えます)。

抽象クラスのメカニズムが C++ にもたらす、「通常の」基本クラスでは達成できない追加の利点は何ですか?

0 投票する
3 に答える
25499 参照

c++ - C++ で純粋仮想関数呼び出しが発生する原因は何ですか?

私は C++ プログラミング クラスを教えており、一般的な C++ バグを診断する方法については十分なエラー クラスを見てきました。ただし、私の直感があまりよくない主要なタイプのエラーが 1 つあります。純粋仮想関数の呼び出しの原因となるプログラミング エラーは何ですか? これを引き起こす最も一般的なエラーは、基本クラスのコンストラクターまたはデストラクターから仮想関数を呼び出すことです。学生のコードのデバッグを支援する際に注意すべきことは他にありますか?

0 投票する
3 に答える
1897 参照

c++ - 完全な純粋仮想クラスの vtable 配置

C++ 仕様に関する私の (限られた) 知識によると、仮想メンバーを持つクラスの vtable は、最初の非純粋な非インライン仮想メソッドの定義に配置されます。コンパイラは、すべての純粋仮想メソッド (インターフェイスなど) を継承するクラスをどのように処理しますか? この場合、vtable はどこに配置されますか?

0 投票する
3 に答える
40125 参照

c++ - C++ の純粋仮想関数の実装とヘッダー ファイル

問題のクラスがファイルに分割されている場合、抽象クラスから継承された純粋仮想関数の実装に問題が*.hあり*.cppます。コンパイラ ( g++) は、純粋な関数が存在するため、派生クラスをインスタンス化できないことを示しています。

これは、method() を 2 回宣言する必要があることを意味しますか? インターフェイス*.hと同様にderived.h? 他に方法はありませんか?

0 投票する
3 に答える
2157 参照

c++ - 仮想関数を使用したVS2010での__purecallの問題 - メソッドがpurecallを取得すると

私は非常に奇妙な問題を抱えています:

基本クラスの 1 つである IEventlistener() を使用します。これは、他の多くのクラスによって実装されます。ほとんどの場合、システムは機能します。しかし今、非常に奇妙な問題が発生しました。

クラス (CGUIService) がインターフェイスを実装すると、1 つのメソッド (VGetListenerName) が期待どおりに機能し、コールスタックをチェックすると、もう 1 つのメソッド (VHandleMessage) が純粋な呼び出しを取得し、理由がわかりません -.- (vtable が何らかの形で取得されるようです)上書きまたは範囲外 ...)

VHandleMessage を呼び出す前に変数を確認できるように、スクリーンショットを作成しました。これはもちろん、デバッグ アサーション R6025 につながります。これは、実装されたメソッドが IEventlistener() の vtable に入力されていないためです。

ハイレゾ: www.fantasyhaze.com/cb/Error_purecall.png www.fantasyhaze.com/cb/Error_purecall.png

誰かが私にヒントをくれることを願っています:)

編集1.)

もう少し説明するために、同じプロセスを示す新しいスクリーンショットを作成しましたが、純粋ではなく、実装されている 2 つの仮想関数を追加しました (時間の理由により、時間がありません)。インターフェイスを使用する各クラスですべてのメソッドを再度実装します)

紫色のものは新しいものです。赤色のものは機能しないものです。オレンジ色のものは以前に存在し、機能し、現在も機能している方法です。

左側で、VGetListenerName、VHandleEvent1、VHandleEvent2 が機能し (デバッグポイント + 現在の位置)、これら 3 つが vtable にあることがわかりますが、重要なもの (赤) ではありません。

高解像度: www.fantasyhaze.com/cb/Error_purecall2.png vtable 問題 2

編集2.)

解決:

主な問題は、CGUIService が IBase から継承することでした。サービスにアクセスするには、各サービスを格納する Service Locator を使用しました。そのため、Instance Getters Service::GetServiceInstance() で static_cast を実行し、サービスを IBase として格納するために static_cast も実行されました。しかし、IEventListener は IBase に実装されておらず、サービスは IEventListener なしで IBase にキャストバックされ、vtable は適切ではありませんでした。現在、IBase は IEventListener を実装しており、static_cast が IEventListener を正しくキャストするため、機能します :)

ヒントの人のためのThx :)

0 投票する
4 に答える
1099 参照

c++ - コンストラクターから間接的に純粋仮想関数を呼び出すと、常に未定義の動作になりますか?

コンパイラを使用して AIX でCppcheckを構築する作業を行っています (前の質問を参照)。チェッカー クラスはすべてクラスから派生し、そのコンストラクターは各オブジェクトをグローバル リストに登録します。xlCCheck

check.h

checkbufferoverrun.h

私が抱えていると思われる問題は、instances().sort()通話にあります。sort()は静的リスト内の各ポインターでCheck::operator<()which 呼び出しを呼び出しますが、リストに追加されたばかりのインスタンスはまだコンストラクターを完全に実行していません (まだ 内にあるため)。したがって、コンストラクターが完了する前にそのようなポインターを呼び出すと、未定義の動作になるはずです。Check::name()instances()CheckCheck::Check()->name()CheckBufferOverrun

これは本当に未定義の動作ですか、それともここで微妙な点が欠けていますか?

への呼び出しが厳密に必要だとは思わないことに注意してくださいsort()。ただし、その効果は、Cppcheck がすべてのチェッカーを決定論的な順序で実行することです。これは、エラーが検出された順序での出力にのみ影響します。これにより、特定の順序での出力が期待されているため、一部のテスト ケースが失敗する原因となります。

更新:上記の質問はまだ(ほとんど)残っています。ただし、コンストラクターでの呼び出しが問題を引き起こさなかった本当の理由sort()(つまり、純粋な仮想関数の呼び出しによるクラッシュ) は、Check::operator<(const Check *)実際にはsort()!によって呼び出されないためだと思います。むしろ、代わりにポインターsort()を比較するように見えます。これは と の両方で発生し、Cppcheck コード自体に問題があることを示しています。g++xlC