OOPの「オブジェクト」と「クラス」は、アセンブリ言語の観点からメモリ内でどのように編成されていますか?


13

オブジェクトはメモリ内でどのように編成されますか?

たとえば、関数はメモリ内のコードの一部であり、スタックやレジスタを介してパラメータを期待し、独自のスタックフレームを処理することを知っています。

しかし、オブジェクトははるかに複雑な構造です。彼らはどのように編成されていますか?各オブジェクトにはメソッドへの「リンク」があり、アドレスを自分自身にそのメソッドに渡しますか?

このトピックの良い説明を見るのは素晴らしいことです。

UPD。私は質問をより正確にし、主に静的型付け言語に興味があります。


4
特に動的に型付けされた言語と静的に型付けされた言語との間で、異なる言語間で大きく異なる場合があります。質問を最も関心のあるオブジェクト指向言語に絞り込めますか?
バートヴァンインゲンシェナウ14

質問を更新したので、動的に型付けされた言語は理解しにくいと思います。
ニコライゴラブ14

回答:


17

動的ディスパッチ(ポリモーフィズム)がない場合、「メソッド」は単なる暗黙の追加パラメーターを伴う糖質関数です。したがって、ポリモーフィックな振る舞いを持たないクラスのインスタンスはstruct、コード生成の目的では基本的にC です。

静的型システムでの古典的な動的ディスパッチには、基本的に1つの主要な戦略があります:vtables。すべてのインスタンスは、その型(最も重要なことはvtable)を参照する1つの追加のポインターを取得します。最も重要なのは、メソッドごとに1つの関数ポインターの配列です。(継承チェーン内の)すべての型のメソッドの完全なセットはコンパイル時にわかっているため、連続したインデックス(Nメソッドの場合は0..N)をメソッドに割り当て、関数ポインターを参照してメソッドを呼び出すことができます。このインデックスを使用するvtable(再びインスタンス参照を追加のパラメーターとして渡します)。

より動的なクラスベース言語の場合、通常、クラス自体はファーストクラスのオブジェクトであり、各オブジェクトは代わりにそのクラスオブジェクトへの参照を持ちます。クラスオブジェクトは、言語に依存する方法でメソッドを所有します(Rubyでは、メソッドはオブジェクトモデルのコア部分であり、Pythonではメソッドは小さなラッパーを備えた単なる関数オブジェクトです)。クラスは通常、スーパークラスへの参照も保存し、継承されたメソッドの検索をそれらのクラスに委任して、メソッドを追加および変更するメタプログラミングを支援します。

クラスに基づいていないシステムは他にもたくさんありますが、大きく異なっているため、興味深いデザインの選択肢を1つだけ選択します。たとえば、Haskellの型クラスとRustの特性)、コンパイル中にメソッドの完全なセットは不明です。これを解決するには、特性ごとに vtableを作成し、特性の実装が必要なときにそれらを渡します。つまり、次のようなコード:

void needs_a_trait(SomeTrait &x) { x.method2(1); }
ConcreteType x = ...;
needs_a_trait(x);

これにコンパイルされます:

functionpointer SomeTrait_ConcreteType_vtable[] = { &method1, &method2, ... };
void needs_a_trait(void *x, functionpointer vtable[]) { vtable[1](x, 1); }
ConcreteType x = ...;
needs_a_trait(x, SomeTrait_ConcreteType_vtable);

これは、vtable情報がオブジェクトに埋め込まれていないことも意味します。たとえば、多くの異なるタイプを含むデータ構造に格納されたときに正しく動作する「特性のインスタンス」への参照が必要な場合は、ファットポインターを 作成できます(instance_pointer, trait_vtable)。これは実際には上記の戦略の一般化です。


5

あなたの質問は非常に広いので、これは「男に魚を与えれば1日餌を与え、魚に教えれば魚を餌にする」ということわざの意味での答えです。

1.オープン情報ソースを調査する

「アセンブリオブジェクト指向プログラミング」のGoogleには、さまざまな関連リソースがリストされています。

例えば国会でのプログラミングオブジェクト指向、イーサン・J.エルドリッジ、2011年12月15日には、第三のリンクとルックスは良いとして来ました

2.既存の手書きコードから学ぶ

OOPが明示的に宣言されている一般的なアセンブリ言語で記述されたソースコードを調べると、その動作を確認できます。

3.コンパイラーによって生成されたコードパターンから学ぶ

選択したOOPコンパイラーによって生成された中間アセンブリー言語ファイルを調べることにより、その動作を確認できます。C ++コンパイラとFreePascalコンパイラの両方を構成して、アセンブリ言語コードへの高レベルOOPコードの転写がどのようになるかを確認できます。

4.常識でパズルを解く

他の回答からのヒントをすでに知っているので、今はかなり手遅れです。しかし、インターネットが非常に簡単に検索できるようになる前、そして苦労して学んだボランティアから無料で数時間以内にあなたが答えを得ることができるサイトがある前に、誰でも無料で利用できる唯一の作業方法は

自問してみてください:「どのように実装しますか?

非常に多くの場合、数日間のバックグラウンド思考プロセスが頭の中で実行され、いくつかの紙草案のデザインを捨てた後、あなたが思いついたソリューションは他のプログラマーが思いついて既に実装したソリューションと非常に似ていることがわかります


これは私の意見に基づいており、OPの質問に直接答えることはできません。上級の高回答ユーザーは自由に投票できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.