問題タブ [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++ で vtable が作成されるのはいつですか?
コンパイラが仮想関数テーブルを作成するのはいつですか?
1) クラスに少なくとも 1 つの仮想関数が含まれている場合。
また
2) 直接の基本クラスに少なくとも 1 つの仮想関数が含まれている場合。
また
3) 階層の任意のレベルにある親クラスに少なくとも 1 つの仮想関数が含まれている場合。
これに関連する質問: C++ 階層で動的ディスパッチを放棄することは可能ですか?
たとえば、次の例を考えてみましょう。
V-Table を含むのはどのクラスですか?
B は f() を virtual として宣言していないので、クラス C は動的ポリモーフィズムを取得しますか?
c++ - Virtual methods chaos, how can I find what causes that?
A colleague of mine had a problem with some C++ code today. He was debugging the weird behaviour of an object's virtual method. Whenever the method executed ( under debug, Visual Studio 2005 ), everything went wrong, and the debugger wouldn't step in that method, but in the object's destructor! Also, the virtual table of the object, only listed it's destructor, no other methods.
I haven't seen this behaviour before, and a runtime error was printed, saying something about the ESP
register. I wish I could give you the right error message, but I don't remember it correctly now.
Anyway, have any of you guys ever encountered that? What could cause such behaviour? How would that be fixed? We tried to rebuild the project many times, restarted the IDE, nothing helped. We also used the _CrtCheckMemory
function before that method call to make sure the memory was in a good state, and it returned true
( which means ok ) . I have no more ideas. Do you?
c++ - 仮想メソッドを使用したC++オブジェクトのサイズ
仮想のオブジェクトサイズについていくつか質問があります。
1)仮想機能
クラスAのサイズは8バイトです....1つの整数(4バイト)と1つの仮想ポインタ(4バイト)それは明らかです!
クラスBのサイズはどれくらいですか?sizeof Bを使用してテストしましたが、12を出力します
クラスBとクラスAの両方に仮想機能がある場合でも、vptrが1つしかないということですか?vptrが1つしかないのはなぜですか?
Cのサイズは20.......です。
この場合、2つのvptrがレイアウトに含まれているようです.....これはどのように発生しますか?2つのvptrは1つはクラスA用で、もう1つはクラスB用だと思います。クラスCの仮想関数用のvptrはありませんか?
私の質問は、継承のvptrの数についてのルールは何ですか?
2)仮想継承
Aのサイズは8バイトです--------------4(int a)+ 4(vptr)= 8
Bのサイズは16バイトです--------------仮想がない場合は4+4 + 4 = 12である必要があります。なぜここにさらに4バイトがあるのですか?クラスBのレイアウトは何ですか?
Cのサイズは12バイトです。-------------- 4 + 4 + 4 = 12.明らかです!
Dのサイズは32バイトです--------------16(クラスB)+ 12(クラスC)+ 4(int d)= 32である必要があります。そうですか?
Aのサイズは8です
Bのサイズは16です
Cのsizeofは16です
sizeofDは28です28= 16(クラスB)+ 16(クラスC)-8(クラスA)+ 4(これは何ですか?)
私の質問は、仮想継承が適用されるときになぜ余分なスペースがあるのですか?
この場合のオブジェクトサイズの基本的なルールは何ですか?
仮想がすべての基本クラスと一部の基本クラスに適用される場合の違いは何ですか?
c++ - 匿名クラスの仮想テーブル
私のコードにはこれに似たものがあります:
これにより、次の出力が得られると予想されます。
GCC(3.4.5だと思います)でコンパイルすると、そうなります。
ただし、これを Visual Studio 2008 でコンパイルして実行すると、次のようになります。
興味深いのは、Base から派生した構造体に名前 ( struct s1 : public Base
) を付けると、正しく動作することです。
あるとすれば、どの動作が正しいですか? VS は単純なだけですか、それとも標準に準拠していますか? ここで重要な何かが欠けていますか?
c++ - サブクラスで呼び出されない C++ 仮想関数
次の単純な状況を考えてみましょう:
言い換えれば:
- A は純粋な仮想クラスです。
- B は、スーパー クラスがなく、非純粋仮想関数が 1 つあるクラスです。
- C は A および B のサブクラスであり、A の純粋仮想関数をオーバーライドします。
私を驚かせたのは、最初の出力です。
コード内で a() を呼び出していますが、 b() が呼び出されます。私の推測では、変数 b がクラス A のサブクラスではないクラス B へのポインターであるという事実に関連していると思いますが、それでもランタイム型は C インスタンスへのポインターです。
Javaの観点から、これを説明する正確なC++ルールは何ですか?奇妙な動作?
c# - ロック付きの関数呼び出しと仮想呼び出しのどちらが速いですか?
現在、スレッドセーフである必要のないクラスがありますが、将来的にはスレッドセーフなバージョンを作成する必要があるかもしれません。私の見方では、関連する関数をロックしてスレッドセーフにするか、仮想化して後で子孫クラスのオーバーライドでロックすることができます。つまり、今日は次のいずれかを実行できます。
または私はこれを行うことができます:
今日、仕事をより速く終わらせるオプションはどれですか?
c++ - インライン仮想関数
C++ では、仮想関数をインライン化できると理解していますが、通常、インライン化のヒントは無視されます。インライン仮想関数はあまり意味がないようです。
そうですか?
インライン仮想関数が優れているケースを挙げられる人はいますか?
c++ - 仮想関数ルックアップをC++でキャッシュできますか?
抽象基本クラスポインタmypointer->foo()で仮想関数呼び出しfoo()があるとします。アプリが起動すると、ファイルの内容に基づいて、特定の具象クラスをインスタンス化することを選択し、そのインスタンスにmypointerを割り当てます。アプリの残りの人生の間、mypointerは常にその具体的なタイプのオブジェクトを指します。この具象型が何であるかを知る方法はありません(動的にロードされたライブラリのファクトリによってインスタンス化される可能性があります)。具象型のインスタンスが最初に作成された後、型が同じままになることを私は知っています。ポインタが常に同じオブジェクトを指しているとは限りませんが、オブジェクトは常に同じ具象型になります。タイプはファイルの内容に基づいているため、技術的には「実行時」に決定されますが、「起動」(ファイルがロードされる)後はタイプが固定されることに注意してください。
ただし、C ++では、アプリの全期間にわたってfooが呼び出されるたびに、仮想関数のルックアップコストを支払います。実行時に具象型が変化しないことを知る方法がないため、コンパイラーはルックアップを最適化できません(これまでで最も素晴らしいコンパイラーであったとしても、動的にロードされた動作を推測することはできません)ライブラリ)。Javaや.NETなどのJITコンパイル言語では、JITは同じタイプが何度も使用されていることを検出し、インラインキャッシュを実行できます。私は基本的に、C++の特定のポインターに対して手動でそれを行う方法を探しています。
このルックアップをキャッシュするC++の方法はありますか?私は、解決策がかなりハックなものかもしれないことを理解しています。ABI /コンパイラの関連する側面を検出する構成テストを記述して、実際に移植可能でなくても「実質的に移植可能」であるようにすることができれば、ABI/コンパイラ固有のハックを受け入れるつもりです。
更新:否定論者へ:これが最適化する価値がなかったとしたら、現代のJITがそれを行うとは思えません。SunとMSのエンジニアは、インラインキャッシュの実装に時間を浪費しており、改善があったことを確認するためにベンチマークを行っていなかったと思いますか?
c++ - 2つのポリモーフィッククラスから継承
次のコードが与えられた
期待する出力が得られます
ただし、の定義をに変更するU
と
私はまだうまくコンパイルし、警告/エラーはありませんが、出力は今です
私が呼び出すことを妨げる仮想宣言についてはどうfoo
ですか?
c++ - C++ 仮想関数呼び出しと boost::function 呼び出しのスピードワイズ
同じ boost::function 呼び出しと比較した場合、単一継承の仮想関数呼び出しがどのくらい速いか知りたいと思っていました。それらはパフォーマンスがほぼ同じですか、それともboost::functionの方が遅いですか?
パフォーマンスはケースごとに異なる場合があることは認識していますが、一般的なルールとして、どちらがより高速で、どの程度ですか?
ありがとう、ギエルメ
- 編集
KennyTM のテストは、私にとって十分に説得力がありました。私自身の目的では、boost::function は vcall よりもそれほど遅くはないようです。ありがとう。