回答編集履歴
5
修正
answer
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
---
|
16
16
|
|
17
|
-
改めて書きますが、コンパイル時に変数の型がわかるからこ
|
17
|
+
改めて書きますが、コンパイル時に変数の型がわかるからこういったことができるのです。動的型付け言語ではこういった方策は基本的には取れないため、別のやり方が必要になります(たとえば属性アクセスなら属性名でハッシュテーブルを探索して拾い上げる、とか)。
|
18
18
|
|
19
19
|
ただし昨今のトレンドとしては、動的型付け言語でも型推論や実行時コンパイルなどの技術を適用して内部的に静的に処理してパフォーマンスを稼ぐ、という方法も出てきています(JavaScriptなど)。この場合は、(実行されるまでの処理は色々と増えますが)本質的な実行のされ方は私の回答で書いたような静的型付けオブジェクト指向言語のやり方とさほど変わりありません。
|
20
20
|
|
4
表現の修正
answer
CHANGED
@@ -12,8 +12,14 @@
|
|
12
12
|
|
13
13
|
`Hoge`クラスのインスタンスの`hoge`から`hoge.fuga()`されていたら`Hoge_fuga(hoge)`に変換されます。ごく簡単に言うとそれだけです。
|
14
14
|
|
15
|
-
|
15
|
+
---
|
16
16
|
|
17
|
+
改めて書きますが、コンパイル時に変数の型がわかるからこれができるのです。動的型付け言語ではこういった方策は基本的には取れないため、別のやり方が必要になります(たとえば属性アクセスなら属性名でハッシュテーブルを探索して拾い上げる、とか)。
|
18
|
+
|
19
|
+
ただし昨今のトレンドとしては、動的型付け言語でも型推論や実行時コンパイルなどの技術を適用して内部的に静的に処理してパフォーマンスを稼ぐ、という方法も出てきています(JavaScriptなど)。この場合は、(実行されるまでの処理は色々と増えますが)本質的な実行のされ方は私の回答で書いたような静的型付けオブジェクト指向言語のやり方とさほど変わりありません。
|
20
|
+
|
21
|
+
(maisumakunさんからのコメントでのご指摘を受けて、上記2段落は投稿当初から修正・追記しています。)
|
22
|
+
|
17
23
|
---
|
18
24
|
|
19
25
|
CやJavaなどを学んだあと、この本(の特に後半)をやるとプログラミング言語の実装について理解が深まると思います。ただし敷居は高いです。
|
3
追記
answer
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
なお、メンバには値型と参照型の二種類があることに留意してください。値型はintなどで、普通オブジェクトの領域にそのまま埋め込まれます。参照型はポインタが埋め込まれ、この場合実体はまた別のメモリ領域に置かれます。たとえば文字列は長さが変わる可能性があり、値型としてしまうと上で書いた方法は破綻してしまいますが、参照型としておけばポインタの長さは一定(64bitとか)なので困りません。
|
8
8
|
|
9
|
-
ついでに書いておくと、あるクラスを継承した新しいクラスでメンバを追加したとします。親クラスにあったメンバのアドレス位置はそのままにしておき、新しいメンバをその後ろに付け加えれば、親クラスにある属性は親クラスの場合と同じ操作で取り出せる訳です。
|
9
|
+
ついでに書いておくと、あるクラスを継承した新しいクラスでメンバを追加したとします。親クラスにあったメンバのアドレス位置はそのままにしておき、新しいメンバをその後ろに付け加えれば、親クラスにある属性は親クラスの場合と同じ操作で取り出せる訳です。親クラスの型の変数に子クラスのインスタンスを代入できる理由がこれです。
|
10
10
|
|
11
11
|
次にメソッドですが、`Hoge`クラスの`fuga`メソッドがあったとして、`Hoge_fuga`関数みたいなものに変換しておきます(名前は説明のための便宜的なものですが)。この際、引数として`this`を渡すようにします。
|
12
12
|
|
2
追記
answer
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
この位置関係はクラスごとに(つまり型ごとに)決まっています。属性アクセスを試みたとして、変数の型は静的型付けならわかるので、あとはアドレス演算でメンバの値を取り出せる訳です。というか、実際はコンパイル時にアドレス演算に変換してしまう訳です。
|
6
6
|
|
7
|
-
なお、メンバには値型と参照型の二種類があることに留意してください。値型は普通オブジェクトの領域にそのまま埋め込まれます。参照型はポインタが埋め込まれ、この場合実体はまた別のメモリ領域に置かれます。たとえば文字列は長さが変わる可能性があり、値型としてしまうと上で書いた方法は破綻してしまいますが、参照型としておけばポインタの長さは一定(64bitとか)なので困りません。
|
7
|
+
なお、メンバには値型と参照型の二種類があることに留意してください。値型はintなどで、普通オブジェクトの領域にそのまま埋め込まれます。参照型はポインタが埋め込まれ、この場合実体はまた別のメモリ領域に置かれます。たとえば文字列は長さが変わる可能性があり、値型としてしまうと上で書いた方法は破綻してしまいますが、参照型としておけばポインタの長さは一定(64bitとか)なので困りません。
|
8
8
|
|
9
9
|
ついでに書いておくと、あるクラスを継承した新しいクラスでメンバを追加したとします。親クラスにあったメンバのアドレス位置はそのままにしておき、新しいメンバをその後ろに付け加えれば、親クラスにある属性は親クラスの場合と同じ操作で取り出せる訳です。
|
10
10
|
|
1
追記
answer
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
まずインスタンスのメンバですが、Cの構造体と同じです。先頭アドレスから何バイト先の何バイトの領域はメンバ`a`で……とかそんな感じで持ちます。
|
4
4
|
|
5
|
-
この位置関係はクラスごとに(つまり型ごとに)決まっています。属性アクセスを試みたとして、変数の型は静的型付けならわかるので、あとはアドレス演算でメンバの値を取り出せる訳です。
|
5
|
+
この位置関係はクラスごとに(つまり型ごとに)決まっています。属性アクセスを試みたとして、変数の型は静的型付けならわかるので、あとはアドレス演算でメンバの値を取り出せる訳です。というか、実際はコンパイル時にアドレス演算に変換してしまう訳です。
|
6
6
|
|
7
7
|
なお、メンバには値型と参照型の二種類があることに留意してください。値型は普通オブジェクトの領域にそのまま埋め込まれます。参照型はポインタが埋め込まれ、この場合実体はまた別のメモリ領域に置かれます。たとえば文字列は長さが変わる可能性があり、値型としてしまうと上で書いた方法は破綻してしまいますが、参照型としておけばポインタの長さは一定(64bitとか)なので困りません。
|
8
8
|
|