C++ における動的バインディングと静的バインディングのアプリケーションについての深い理解

高洛峰
リリース: 2016-12-26 16:21:18
オリジナル
1085 人が閲覧しました

C++ のポリモーフィズムをサポートするために、動的バインディングと静的バインディングが使用されます。それらの違いを理解することは、ポリモーフィズムをより深く理解し、プログラミング中の間違いを避けるのに役立ちます。
次の 4 つの名詞を理解する必要があります:
1. オブジェクトの静的型: オブジェクトが宣言されたときに使用される型。これはコンパイル時に決定されます。
2. オブジェクトの動的タイプ: 現在指されているオブジェクトのタイプ。これは実行時に決定されます。オブジェクトの動的タイプは変更できますが、静的タイプは変更できません。
オブジェクトの静的型と動的型については、例を見てください:

class B
{
}
class C : public B
{
}
class D : public B
{
}
D* pD = new D();//pD的静态类型是它声明的类型D*,动态类型也是D*
B* pB = pD;//pB的静态类型是它声明的类型B*,动态类型是pB所指向的对象pD的类型D*
C* pC = new C();
pB = pC;//pB的动态类型是可以更改的,现在它的动态类型是C*
ログイン後にコピー

3. 静的バインディング: バインドされるのは、オブジェクトの静的型です。特定の機能 (関数など) は、オブジェクトの静的型に依存します。コンパイル時に発生するオブジェクト。
4. 動的バインディング: バインドされるのはオブジェクトの動的タイプであり、特定の機能 (関数など) はオブジェクトの動的タイプに依存し、実行時に発生します。

class B
{
    void DoSomething();
    virtual void vfun();
}
class C : public B
{
    void DoSomething();//首先说明一下,这个子类重新定义了父类的no-virtual函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态绑定才这样使用。
    virtual void vfun();
}
class D : public B
{
    void DoSomething();
    virtual void vfun();
}
D* pD = new D();
B* pB = pD;
ログイン後にコピー

見てみましょう、pD->DoSomething() と pB->DoSomething() は同じ関数を呼び出しますか?
いいえ、pD と pB は両方とも同じオブジェクトを指します。関数 DoSomething は非仮想関数であるため、静的にバインドされます。つまり、コンパイラーはコンパイル時にオブジェクトの静的型に基づいて関数を選択します。 pD の静的型は D* であるため、コンパイラは pD->DoSomething() を処理するときにそれを D::DoSomething() にポイントします。同様に、pB の静的型が B* である場合、pB->DoSomething() は B::DoSomething() を呼び出します。
もう一度見てみましょう、pD->vfun() と pB->vfun() は同じ関数を呼び出しますか?
はい。 vfun は仮想関数であるため、動的にバインドされます。つまり、pB と pD は異なる静的型を持ちますが、同時にオブジェクトを指し、その動的型は次のようになります。これは D* なので、同じ関数 D::vfun() を呼び出します。
上記はすべてオブジェクト ポインターに関するものであり、同じことが参照にも当てはまります。
ポインターと参照の動的型と静的型は矛盾している可能性がありますが、オブジェクトの動的型と静的型は一貫しています。
D D;
D.DoSomething() と D.vfun() は常に D::DoSomething() と D::vfun() を呼び出します。
動的にバインドされるものと静的にバインドされるものについては、非常によくまとめた記事があります:
それを一文にまとめました: 仮想関数のみが動的バインディングを使用し、それ以外はすべて静的バインディングです。今のところ、この文に当てはまらないものは見つかりませんでした。もし間違いがあれば、ご指摘いただければ幸いです。
特に注意が必要なこと
デフォルトのパラメータと仮想関数が一緒に現れる場合、状況が少し複雑になり、間違いを犯しやすくなります。仮想関数が動的にバインドされていることはわかっていますが、実行効率を高めるために、デフォルトのパラメーターは静的にバインドされています。

class B
{
 virtual void vfun(int i = 10);
}
class D : public B
{
 virtual void vfun(int i = 20);
}
D* pD = new D();
B* pB = pD;
pD->vfun();
pB->vfun();
ログイン後にコピー
上記の分析から、pD->vfun() と pB->vfun() は両方の関数 D::vfun() を呼び出していることがわかりますが、それらのデフォルトのパラメーターは何でしょうか?
分析すると、pD->vfun() の場合、pD の静的型は D* であるため、そのデフォルト パラメーターは同様に 20 である必要があります。 10になります。コードを書いて検証したところ、正しいです。
この機能を好む人はいないでしょう。したがって、常に覚えておいてください:
「関数の継承されたデフォルトのパラメーター値を再定義しないでください。」
C++ 言語について
現在、私は基本的に C++ の「オブジェクト指向プログラミング」のサブセットにいます。より複雑な知識。それでも、これまでにもプログラミングで注意すべき点はたくさんあり、今後もさらに多くなる可能性があります。これが、多くの人が C++ に反対する理由かもしれません。

c++ は、Google の 4 つの公用語の 1 つです。しかし、確かにGoogleは近年go言語を立ち上げており、その位置づけはc/c++に似ています。この状況を考えると、おそらく Google のプログラマーは C++ の複雑さを深く認識しているため、C++ の代替言語を開発したいと考えているのではないかと思います。時間があれば、Go 言語について学び、C++ などの問題で Go 言語がどのように選択を行うかを確認するとよいでしょう。

C++ での動的バインディングと静的バインディングのアプリケーションをより深く理解するには、PHP 中国語 Web サイトの関連記事に注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート