2013-08-03 20 views
20

初期バインディングとレイトバインディングはC++のように見えますか?あなたは例を挙げることができますか?C++で初期(静的)バインディングと遅延(動的)バインディングとは何ですか?

私はその関数のオーバーロードは早いバインディングであり、仮想関数はレイトバインディングであると読んでいます。私はread "早期(または静的)バインディングはコンパイル時バインディングを指し、後半(または動的)バインディングは実行時バインディングを指す"と述べています。

+1

* "[...]早期(または静的)バインディングはコンパイル時バインディングを指し、後半(または動的)バインディングは実行時バインディングを指します" * .....はい、すべてです。他に何を知りたいですか?あなたの質問/混乱/疑念は何ですか? – Nawaz

+0

これは前に尋ねられなかったとは思わない。 – Shoe

+2

のための新しい例を書いている非常に古い話題。これを見てください[リンク](http://www.learncpp.com/cpp-tutorial/124-early-binding-and-late-binding/) – loxxy

答えて

19

あなたは正しく読んでいます。

using FuncType = int(*)(int,int); // pointer to a function 
            // taking 2 ints and returning one. 

int add(int a, int b) { return a + b; } 
int substract(int a, int b) { return a - b; } 

スタティックバインディングがコンパイル時に知られているとき、結合:基本的な例を用いて与えられることができる

int main() { 
    std::cout << add(4, 5) << "\n"; 
} 

は、静的にバインドされ、従って操作の動的な変化の余地を残さない、と。

int main() { 
    char op = 0; 
    std::cin >> op; 

    FuncType const function = op == '+' ? &add : &substract; 

    std::cout << function(4, 5) << "\n"; 
} 

ここで、入力に応じて、9または-1が得られます。これは動的にバインドされています。

さらに、オブジェクト指向言語では、virtual関数を使用して何かを動的にバインドすることができます。より詳細な例は、このようになり得る:

struct Function { 
    virtual ~Function() {} 
    virtual int doit(int, int) const = 0; 
}; 
struct Add: Function { 
    virtual int doit(int a, int b) const override { return a + b; } 
}; 
struct Substract: Function { 
    virtual int doit(int a, int b) const override { return a - b; } 
}; 

int main() { 
    char op = 0; 
    std::cin >> op; 

    std::unique_ptr<Function> func = 
     op == '+' ? std::unique_ptr<Function>{new Add{}} 
        : std::unique_ptr<Function>{new Substract{}}; 

    std::cout << func->doit(4, 5) << "\n"; 
} 

前の例と意味的に等価である...しかし、オブジェクト指向プログラミングでは一般的であるvirtual機能によって遅延バインディング導入します。

+1

固定アドレスのオフセットとvtableを言及する価値がありますルックアップ。 –

+3

@NikosC:既に仮想メソッドを追加していました。私は初心者の質問に見えるものに対応するためにvtables/v-ptrを追加するような気がしません。それはちょっと深すぎるかもしれません。 –

+0

申し訳ありませんが、 "FuncType = int(*)(int、int)を使用して"という行を理解できません。 – Slazer

3

これは、C++だけでなく、すべてのオブジェクト指向言語に当てはまります。

スタティックコンパイルのバインディングは簡単です。多形性は関与していません。コードを記述してコンパイルして実行するときには、オブジェクトの型がわかります。時には犬は単なる犬です。

動的ランタイムバインディングは、ポリモフィズムの由来です。

コンパイルタイプで親タイプの参照がある場合は、実行時にそれに子タイプを割り当てることができます。実行時に参照の動作が魔法のように適切な型に変わります。仮想テーブルの参照が実行され、動的タイプが何であるかがランタイムに把握されます。

+0

注:C++は単なるオブジェクト指向言語にとどまらず、遅延バインディングを使用する方法が増えています。たとえば、関数ポインタは一方向です(実際には仮想関数を実装するためにテーブルの下で使用されます)。 –

+0

はい、Pythonでも当てはまります。私はこの考え方がC++を超えていることを指摘したがっている。 – duffymo

0

スタティックバインディング: コンパイル時に関数呼び出しがわかっている場合は、静的バインディングと呼ばれます。それに応じて適切な関数が呼び出されます。以下の例に示すように、obj_a.fun()はobj_aがクラスAであるため、classのfun()が呼び出されます。

#include<iostream> 
using namespace std; 
class A{ 
public: 
void fun() 
{cout<<"hello world\n";} 

}; 
class B:public A{ 
public: 
void show() 
{cout<<"how are you ?\n";} 

}; 

int main() 
{ 
A obj_a;   //creating objects 
B obj_b; 
obj_a.fun();  //it is known at compile time that it has to call fun() 
obj_b.show();  //it is known at compile time that it has to call show() 
return 0; 
} 

ダイナミックバインディング: 関数呼び出しが実行時に知られているならば、それは動的結合として知られています。仮想キーワードを使用してレイトバインディングを実現します。ベースポインタは、子ポインタのアドレスも保持できます。そうmatter.whetherポインタのポインタのこのコンテンツでは、我々は車のクラスから仮想キーワードを削除した場合、それは車のクラスの関数を呼び出します、基本クラスのアドレスまたは子クラス

#include<iostream> 
using namespace std; 

class car{ 
public: 
    virtual void speed() 
    { 
     cout<<"ordinary car: Maximum speed limit is 200kmph\n"; 
    } 
}; 
class sports_car:public car{ 
    void speed() 
    { 
     cout<<"Sports car: Maximum speed is 300kmph\n"; 
    } 
}; 

int main() 
{ 
car *ptr , car_obj;  // creating object and pointer to car 
sports_car sport_car_obj; //creating object of sport_car 
ptr = &sport_car_obj;  // assigining address of sport_car to pointer 
          //object of car 
ptr->speed(); // it will call function of sports_car 

return 0; 
} 

を保持しています。今はsport_carクラスのスピード機能を呼んでいます。 これは、ポインタの内容ではなくポインタの内容を呼び出す関数中の動的バインディングです。 ptrは車種ですがsport_carのアドレスを保持しているためsport_car speed()が呼び出されます。

関連する問題