問題タブ [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++ - 仮想機能が非公開になるのはなぜですか?
私はいくつかのコードでこれを見つけました:
これには何か目的がありますか?
(私はいくつかのコードを VS から G++ に移植しようとしていますが、これが私の注意を引きました)
c# - ベースコンストラクタからの仮想メソッドの呼び出しを回避する方法
ライブラリに抽象クラスがあります。このクラスの派生を適切に実装するのをできるだけ簡単にするようにしています。問題は、3つのステップのプロセスでオブジェクトを初期化する必要があることです。ファイルを取得し、いくつかの中間ステップを実行してから、ファイルを操作します。最初と最後のステップは、派生クラスに固有です。これは簡略化された例です。
もちろん、問題はコンストラクターでの仮想メソッド呼び出しです。ライブラリの利用者は、派生クラスが完全に初期化されていることを期待できない場合、クラスを使用するときに制約を受けることになります。
Initialize()
コンストラクターから保護されたメソッドにロジックを引き出すことはできますが、実装者はを呼び出す代わりStep1()
にStep3()
直接呼び出すことができますInitialize()
。Step2()
問題の核心は、スキップしても明らかなエラーが発生しないことです。特定の状況でのひどいパフォーマンス。
いずれにせよ、図書館の将来のユーザーが回避しなければならない深刻で自明ではない「落とし穴」があるように感じます。この種の初期化を実現するために使用する必要のある他の設計はありますか?
必要に応じて詳細を提供できます。私は問題を表現した最も単純な例を提供しようとしていました。
c++ - 派生、具象、クラスの vtable
1 つの基本クラスがあり、そこから 10 個の異なる具体的な派生クラスを派生させた場合、すべての具体的な派生クラスはそれぞれ異なる vtable を持ちますか?
php - PHPでの仮想関数の正しい実装?
私の職場 (php のみ) には、データベース抽象化のための基本クラスがあります。新しいデータベース テーブルをベース レイヤーに追加する場合は、このベース クラスのサブクラスを作成し、いくつかのメソッドをオーバーライドして、このテーブルを使用するための個々の動作を定義する必要があります。通常の動作は同じままである必要があります。
今では、デフォルトの動作のメソッドをオーバーライドするだけの新しいプログラマーを会社でたくさん見てきました。すべてのデフォルトの動作を入れて、好きな場所に個々のものを追加するだけで「いい」ものもあれば、基本クラスとその継承者を使用しようとして自殺するものもあります。
この問題を解決するために私が最初に考えたのは、継承クラスによってオーバーライドされるべき抽象メソッドについて考えることでした。しかし、抽象メソッドに対する他の引数のほかに、「抽象」は、ベースクラスを単独で使用できない理由と、これらの関数をオーバーライドする必要がある理由を示していません。
いくつかグーグルで調べた後、PHPで「実際の」仮想関数を実装するための良い答えが見つかりませんでした(具体的な実装のすべての希望をほとんど殺してしまう仮想関数があるだけです)。
それで、あなたはこの問題をどうしますか?
c++ - 仮想関数を持つ基本クラスから継承するクラスのsizeof
次のコードフラグメントの場合。
私が気付いたように見える動作は、空のクラスがインスタンス化されるか、空のクラスがバイト境界から継承されるときはいつでも考慮されない(つまり、サイズ1バイトのオブジェクトが許可される)場合、他のすべての場合、オブジェクトサイズは次のように決定されるようです。バイト境界。
これの理由は何ですか?この時点で私は推測しているので、私は尋ねます。
c++ - C ++スタイル:オーバーライドされたメソッドの前に仮想キーワードを付ける
オーバーライドされたメソッドの前にvirtualキーワードを付けるのか、それとも元の基本クラスでのみ接頭辞を付けるのかについて、同僚と話し合っています。
私はすべての仮想メソッド(つまり、vtableルックアップを含むメソッド)の前にvirtualキーワードを付ける傾向があります。私の理論的根拠は3つあります。
C ++にオーバーライドキーワードがない場合、仮想キーワードの存在は、少なくともメソッドがルックアップを含み、理論的にはさらなる特殊化によってオーバーライドされるか、より高い基本クラスへのポインターを介して呼び出される可能性があることを通知します。
このスタイルを一貫して使用するということは、仮想キーワードのないメソッド(少なくともコード内)を見ると、最初はそれがベースから派生したものでも、サブクラスに特化したものでもないと想定できることを意味します。
何らかのエラーによって仮想がIFooから削除された場合でも、すべての子は引き続き機能します(CFooSpecialization :: DoBarは、単に非表示にするのではなく、CFooBase :: DoBarをオーバーライドします)。
私が理解したように、この慣行に反対する議論は、「しかし、その方法は仮想的ではない」(これは無効であり、仮想性の誤解から生まれたと私は信じている)、そして「仮想キーワードを見ると、誰かがそれから派生していて、それらを探しに行くことを意味します。」
架空のクラスは複数のファイルに分散している可能性があり、いくつかの専門分野があります。
様式的には、2つの派生クラスから仮想キーワードを削除しますか?もしそうなら、なぜですか?ここでStackOverflowの考えは何ですか?
c++ - C ++コンストラクターでポリモーフィックな動作を取得するにはどうすればよいですか?
私はこのようになりたい基本クラスを持っています:
重要なのは、派生クラスを強制的にオーバーライドI
し、各オブジェクトが構築されるときに強制的に呼び出されるようにすることです。これはいくつかの簿記を行うために使用され、どのタイプのオブジェクトが構築されているかを知る必要があります(ただし、それ以外の場合は、現在のオブジェクトを基本クラスとして扱います)。
C ++ではコンストラクターから抽象仮想関数を呼び出せないため、これは機能しません。
同じ効果を得る方法はありますか?
このリンクに基づくと、答えは私が欲しいものを手に入れる方法がないということのように思われます。しかしそれが言うことは:
簡単な答えは:いいえ。基本クラスは、それがどのクラスから派生したかについては何も知りません。それも良いことです。
[...]
つまり、コンストラクターDerived1 :: Derived1が開始するまで、オブジェクトは正式にはDerived1のインスタンスにはなりません。
しかし、私の場合、それが何であるかを知りたくはありませんが、それがどうなるかを知りたくありません。実際、ユーザーが(事後に)クラスにマップできる限り、何が返されるかは気にしません。だから私はリターンポインタのようなものを使ってそれを回避することさえできた。
(今、そのリンクを読むことに戻ります)
c++ - テンプレート クラス + 仮想関数 = 実装する必要がありますか?
このコード:
を呼び出さない限り、問題なく簡単にコンパイルできますa.DoSomething()
。
However, if I define DoSomething
as a virtual function, I will get a compile error saying that B
doesn't declare SomeFunction
. I can somewhat see why it happens (DoSomething should now have an entry in the vtable), but I can't help feeling that it's not really obligated. Plus it sucks.
Is there any way to overcome this?
EDIT 2: Okay. I hope this time it makes sence: Let's say I am doing intrusive ref count, so all entities must inherit from base class Object. How can I suuport primitive types too? I can define:
を使うことができます...しかし、どうPrimitive<int>
ですか?フロートには演算子がないため、問題のようです。しかし、実際にはそうではありません。これは、テンプレートの意図的な機能の 1 つです。Primitive<char>
Primitive<float>
%=
operator %=
Primitive<float>
何らかの理由で、operator %=
仮想と定義する場合。Primitive<float>
または、リンク エラーを回避するために dll から事前にエクスポートする場合operator %=
、Primitive<float>
. operator %=
inPrimitive<float>
の vtableにダミーの値を入力するだけであれば(例外が発生しますか?)、すべて問題ありませんでした。