静的な型と動的な型の意味が知りたい。


オブジェクト指向で「静的な型と動的な型」という用語が出てきたのですが、説明を読んでもわかりません。参考書には以下のように書かれているのですが、"式"というところで引っ掛かり結果よくわからないまま参考書を読み進めていましたが理解している前提での説明が続いてその先の理解できないので別の説明をしてもらいたく質問しました。

* * *

**静的な型**

> 「静的な型
> 式の型、その式がもたらす結果の型として実行時の意味を考慮ぜずにプログラムを解析することで得られる。式の静的な型は、その式が位置するプログラムの形だけから決まり、プログラムの実行中に変わることがない。」

**動的な型**

> 「動的な型。左辺値式の表す左辺値が指す最派生オブジェクト型。(例)
> その静的な型がクラスBへのポインタであるポインタｐがクラスBから派生したクラスDのオブジェクトを指していたとすると、式*pの動的な型はDとなる、参照も同様に扱う。右辺値式の動的な型は、それの静的な型とする。」

* * *
[code]

            void put_member(const Member* m) {
                cout << (m->get_weight() >= 65 ? "〇" : "　");
                m->print();//ここです。
            }
    
            int main() {
    
                Member m("mmm", 15, 75.2);
                VipMember v("aaa", 17, 89.2, "会費全額免除");
                SeniorMember s("sss",43,63.7,3);
    
                put_member(&m);
                put_member(&v);
                put_member(&s);
    
                _getch();
                return 0;
            }
    
[/code]




難しく考えすぎです。  
とりあえず「式」という単語を使わない説明をしてみます。

提示サンプルが断片的過ぎて、そのサンプルではコメントできないです。  
[c++ 仮想関数の利点について](https://ja.stackoverflow.com/questions/47194/)  
のコードをサンプルとして使います。

[code]

    b* p=&d;
    
[/code]

において、静的な型とは  
- `p` はソースコード上 `b*` と書かれていますから `b*` が静的な型  
- `&d` はソースコード上 `d1*` と読めるので `d1*` が静的な型
[code]

    p->f1();
    
[/code]

`p->` は `(*p).` の省略形だと思い出してください。ここで

  * `*p` の静的な型とはソースコードを素直に読んだ `b` 型のこと
  * `*p` の動的な型とはこの例では `d1` 型のことです。

先の例ではソースコードが簡単すぎて「読むだけ」で動的な型が判断できてしまいますが、もう少し実用的なサンプルコードを示すと

[code]

    void func(b* p) { p->f1(); }
    int main() {
        b x; func(&x);
        d1 y; func(&y);        
    }
    
[/code]

のようになります。この場合 `func` 中の `*p` の

  * 静的な型は `b`
  * 動的な型は `b` か `d1` か、実行するまでわからない（１回目は `b` ２回目は `d1` ）

ってことです。




難しく考えすぎです。  
とりあえず「式」という単語を使わない説明をしてみます。

提示サンプルが断片的過ぎて、そのサンプルではコメントできないです。  
[c++ 仮想関数の利点について](https://ja.stackoverflow.com/questions/47194/)  
のコードをサンプルとして使います。

[code]

    b* p=&d;
    
[/code]

において、静的な型とは  
- `p` はソースコード上 `b*` と書かれていますから `b*` が静的な型  
- `&d` はソースコード上 `d1*` と読めるので `d1*` が静的な型
[code]

    p->f1();
    
[/code]

`p->` は `(*p).` の省略形だと思い出してください。ここで

  * `*p` の静的な型とはソースコードを素直に読んだ `b` 型のこと
  * `*p` の動的な型とはこの例では `d1` 型のことです。

先の例ではソースコードが簡単すぎて「読むだけ」で動的な型が判断できてしまいますが、もう少し実用的なサンプルコードを示すと

[code]

    void func(b* p) { p->f1(); }
    int main() {
        b x; func(&x);
        d1 y; func(&y);        
    }
    
[/code]

のようになります。この場合 `func` 中の `*p` の

  * 静的な型は `b`
  * 動的な型は `b` か `d1` か、実行するまでわからない（１回目は `b` ２回目は `d1` ）

ってことです。

