2013-08-03 28 views
20

Come appare l'associazione anticipata e tardiva in C++? Puoi dare un esempio?Che cos'è l'associazione anticipata (statica) e tardiva (dinamica) in C++?

Ho letto che l'overloading delle funzioni è l'associazione anticipata e le funzioni virtuali sono in ritardo. I read che "il binding in anticipo (o statico) fa riferimento al binding in fase di compilazione e il binding in ritardo (o dinamico) fa riferimento al binding in runtime".

+1

* "[...] il binding precoce (o statico) fa riferimento al binding in fase di compilazione e il binding tardivo (o dinamico) fa riferimento al binding in runtime" * ..... Sì, questo è tutto. Cos'altro vuoi sapere? Qual è la tua domanda/confusione/dubbio? – Nawaz

+0

Non riesco a credere che non sia stato chiesto prima. – Shoe

+2

Argomento molto vecchio per scrivere nuovi esempi per. Date un'occhiata a questo [collegamento] (http://www.learncpp.com/cpp-tutorial/124-early-binding-and-late-binding/) – loxxy

risposta

19

Avete letto bene. L'esempio di base può essere fornita con: legame

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; } 

statico è quando associa è noto al momento della compilazione:

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

non lascia spazio per un cambiamento dinamico del funzionamento, e quindi è vincolato staticamente.

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

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

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

mentre qui, a seconda dell'input, si ottiene 9 o -1. Questo è legato dinamicamente.

Inoltre, nelle lingue orientate agli oggetti, le funzioni virtual possono essere utilizzate per associare dinamicamente qualcosa. Un esempio più dettagliato potrebbe quindi essere:

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"; 
} 

semanticamente equivalente all'esempio precedente ... ma introduce tardiva da virtual funzione che è comune in programmazione orientata agli oggetti.

+1

Forse è anche la pena menzionare offset di indirizzi fissi vs vtable le ricerche. –

+3

@NikosC .: stavo già aggiungendo metodi virtuali; Non mi sento affatto di aggiungere vtables/v-ptr in risposta a quella che sembra essere la domanda di un principiante. Potrebbe essere un po 'troppo approfondito. –

+0

Mi dispiace ma non capisco la riga "usando FuncType = int (*) (int, int)" – Slazer

3

Questi sono veri per tutti i linguaggi orientati agli oggetti, non solo per C++.

Il binding statico e di compilazione è facile. Non c'è alcun polimorfismo coinvolto. Conosci il tipo di oggetto quando scrivi, compili ed esegui il codice. A volte un cane è solo un cane.

Dinamico, il legame di runtime è da dove viene il polimorfismo.

Se si dispone di un riferimento di tipo padre in fase di compilazione, è possibile assegnargli un tipo figlio in fase di runtime. Il comportamento del riferimento cambierà magicamente al tipo appropriato in fase di esecuzione. Verrà eseguita una ricerca nella tabella virtuale per consentire al runtime di determinare il tipo dinamico.

+0

Nota: C++ è più di un semplice linguaggio orientato agli oggetti, e quindi ha più modi di usare l'associazione tardiva. I puntatori di funzione, ad esempio, sono unidirezionali (e utilizzati al di sotto delle tabelle per implementare effettivamente le funzioni virtuali). –

+0

Sì, anche vero per Python. Volevo solo sottolineare che l'idea si estende oltre il C++. – duffymo

0

Collegamento statico: se la chiamata della funzione è nota al momento della compilazione, viene definita associazione statica. nel tipo di oggetto statico vincolante, viene chiamata una funzione adeguata. come mostrato nell'esempio qui sotto obj_a.fun() qui obj_a è di classe A è per questo che viene chiamato fun() della classe.

#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; 
} 

dinamica vincolante: se la funzione chiamante è noto in fase di esecuzione, allora è conosciuto come binding dinamico. otteniamo l'associazione tardiva utilizzando la parola chiave virtuale. Anche il puntatore di base può contenere l'indirizzo dei puntatori figlio. Quindi, in questo contenuto del puntatore matter.whether puntatore sta tenendo l'indirizzo della classe base o classe figlia

#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; 
} 

se togliamo parola chiave virtuale da vettura di classe allora chiamerà funzione della classe di auto. ma ora sta chiamando la funzione di velocità della classe sport_car. questo è un collegamento dinamico poiché durante la chiamata la funzione del contenuto del puntatore non è il tipo di puntatore. come ptr è di tipo auto ma con l'indirizzo di sport_car è per questo che viene chiamata sport_car speed().

Problemi correlati