Mi a korai és késői kötés?
On november 18, 2020 by adminFolyamatosan hallok a korai és késői kötésről, de nem értem, hogy mik azok. A következő magyarázatot találtam, amelyet nem értek:
A korai kötés az értékek változókhoz való hozzárendelését jelenti a tervezési idő alatt, míg a késői kötés az értékek hozzárendelését jelenti. a változókhoz a futási idő alatt.
Meg tudná adni valaki, hogy meghatározza a kétféle kötést, és összehasonlíthatja őket?
Megjegyzések
- fordítási idő vs futásidejű fordítás.
- Íme egy jó olvasnivaló a témáról: hu.wikibooks.org/ wiki / Bevezetés_programozás_nyelvekre / …
Válasz
Két fő fogalom van a zavarodottságban: a kötés és a betöltés. Összekeveri a DataBinding fogalma, amely valahol a közepén van, gyakran mindkettőt végzi. Miután megfontoltam, hozzá fogok adni még egy fogalmat a trifecta, a diszpécser befejezéséhez.
Típusok
Késői kötés : a típus ismeretlen , amíg a változó futás közben nem kerül végrehajtásra; általában a hozzárendelés útján, de vannak más eszközök a típus kényszerítésére; a dinamikusan beírt nyelvek ezt alapjellemzőnek nevezik, de sok statikusan beírt nyelv rendelkezik valamilyen módszerrel a késői kötés elérésére. a dinamikus feladás kölcsönzésével és kiterjesztésével
Korai kötés : típus ismert mielőtt a változó futás közben gyakorolható lenne, általában statikus, deklaratív eszközökkel
Gyakran implementálva szokásos primitív típusokkal
Funkciók
Statikus feladás : ismert, specifikus funkció vagy szubrutin fordításkor; egyértelmű és aláírással illeszkedik
Statikus függvényként valósítja meg; egyetlen metódusnak sem lehet ugyanaz az aláírása
Dinamikus elküldés : nem egy adott függvény vagy szubrutin a fordítás idején; a végrehajtás során a kontextus határozza meg. Kétféle megközelítés létezik a “dinamikus diszpécser” számára, megkülönböztetve azzal, hogy milyen kontextus-információk alapján választják ki a megfelelő funkció megvalósítását.
In single [ dynamic ] dispatch , csak a példány típusát használjuk a függvény megfelelő megvalósításának meghatározásához. A statikusan tipizált nyelvekben ez a gyakorlatban azt jelenti, hogy a példánytípus dönti el, hogy melyik módszer megvalósítását alkalmazzák, függetlenül a változó deklarálásakor / hozzárendelésekor jelzett referencia típustól. Mivel csak egyetlen típust – az objektumpéldány típusát – használnak a megfelelő megvalósítás kikövetkeztetésére, ezt a megközelítést “egyszeri feladásnak” hívják.
Van még többszörös [ dynamic ] feladás , ahol a bemeneti paraméterek szintén segítenek meghatározni, hogy melyik függvény megvalósítását hívják meg. Mivel több típus – mind a példány, mind a a paraméter (ek) típusa (i) befolyásolja melyik módszer megvalósítása van kiválasztva, ezt a megközelítést “többszörös elküldésnek” nevezik.
Virtuális vagy absztrakt funkcióként valósítják meg; az egyéb nyomok felülbírált, rejtett vagy árnyékolt módszereket tartalmaznak.
NB: Az, hogy a módszer túlterhelése dinamikus elküldést tartalmaz-e, nyelvspecifikus. Például a Java-ban a túlterhelt metódusok statikusan kerülnek elküldésre.
Értékek
Lusta betöltése : az objektum inicializálási stratégiája, amely szükségig elhalasztja az érték hozzárendelését ; lehetővé teszi, hogy egy objektum lényegében érvényes, de tudatosan hiányos állapotban legyen, és várjon, amíg az adatokra szükség van, mielőtt betöltené őket; gyakran különösen hasznosnak bizonyul nagy adatállományok betöltése vagy külső erőforrásokra való várakozás esetén.
Gyakran úgy valósítják meg, hogy a konstruktor vagy az inicializálási hívások során célzottan nem töltenek be egy gyűjteményt vagy listát egy összetett objektumba, amíg valamelyik downstream hívó nem kéri a az a gyűjtemény (pl. get_value_at, get_all_as stb.).A variációk között szerepel a gyűjtemény metaadatainak betöltése (például méret vagy kulcsok), de a tényleges adatok kihagyása; emellett néhány futásidejű mechanizmust is biztosít a fejlesztők számára egy meglehetősen biztonságos és hatékony szingulett megvalósítási sémával.
Kíváncsian töltődik : objektum inicializálási stratégia, amely azonnal elvégzi az összes érték-hozzárendelést annak érdekében, hogy az összes szükséges adat teljes legyen, mielőtt érvényes állapotúnak tekintené magát.
Gyakran megvalósítja az összetett objektumok összes ismert adata a lehető leghamarabb rendelkezésre bocsátása, például egy konstruktor hívása vagy inicializálása során.
Adatkötés : gyakran magában foglal egy aktív kapcsolat vagy térkép létrehozását két kompatibilis információáramlat között úgy, hogy az egyik változása visszatükröződjön a másikba és fordítva; A kompatibilitás érdekében gyakran közös alaptípussal vagy interfésszel kell rendelkezniük.
Gyakran próbálják tisztább, következetes szinkronizálást biztosítani a különböző alkalmazási szempontok között (pl. nézet-modell a megtekintéshez, modell-vezérlő stb.), és olyan fogalmakról beszél, mint a forrás és a cél, a végpontok, a lekötés / kikapcsolás, a frissítés és az olyan események, mint az on_bind, on_property_change, on_explicit, on_out_of_scope
MEGJEGYZÉS SZERKESZTÉSSÉGÉRT: A leírás megadásához az utolsó nagyobb szerkesztés szükséges példák ezek gyakoriságára. Az egyes kódpéldák teljes mértékben a / runtime / platform implementációtól függenek.
Megjegyzések
- Ez a válasz túl specifikusnak tűnik az objektumorientált nyelveknél.
- @Jack ezt nem érzem ‘, úgy gondolom, hogy ez egy kiváló szempont, amely sok szempontot lefed.
Válasz
Bármi, amit a fordító dönt a fordítás közben, utalhat a KORAI / ÖSSZEÁLLÍTÁSI IDŐRE A kötést és mindent, amit a RUNTIME időpontban kell eldönteni, LATE / RUNTIME kötés.
Például
Túlterhelés és a módszer túlterhelése .
1 ) A metódus túlterhelésében a metódus az ar metódusokra hív A fordító abban az értelemben dönt, hogy melyik függvényt fogják meghívni, a fordító a fordítás idején dönt. Ezért KORAI KÖTÉS .
2) Az Overriding módszerben a RUNTIME-nál eldől, hogy melyik módszer hívni fogják. Tehát KÉT KÖTÖTÉS néven jelenik meg.
Igyekezett egyszerűvé és könnyen megszerezhetővé tenni. Remélem, ez segít.
Válasz
A késői kötés az, amikor a viselkedést futás közben értékelik. Erre akkor van szükség, ha valóban meg akarja határozni, hogyan kell cselekedni az információk alapján, amelyek csak akkor vannak, amikor a program fut. Véleményem szerint a legegyértelműbb példa a virtuális függvény mechanizmusa, különösképpen a C ++ nyelven. ed2c2e9173 “>
Ebben a példában a a->f()
valóban felhívja a (z) void A::f()
-t, mert korán (vagy statikusan) ) kötött, és így a program futás közben úgy gondolja , hogy csak egy A
típusú változó mutatója, míg a->g()
valójában felhívja a (z) void B::g()
fájlt, mert a fordító, látva, hogy g()
virtuális, kódot ad be, hogy megkeresse a helyes függvény címét futás közbeni híváshoz.
Megjegyzések
- ” A futásidejű “? ‘ a C ++ -ról beszél. A C ++ egyenesen a gépi kódra fordít, nem kell ‘ futási idő a megoldáshoz virtuális módszerek.
- @tdammers A C ++ valójában futtatási idő könyvtárra van szükség, bár nem virtuális hívásokhoz. Ha figyelmesen olvas, ‘ észreveszi, hogy ez a válasz azt mondja, hogy a fordító ” kódot injektál a helyes funkció címének megkereséséhez [ …] a futás közben “.
- Nos, de ez a ” kód a helyes függvény címének megkeresése ” alapvetően csak egy típus-agnosztikus kétlépéses mutató-eltérítés, amelyet egy függvényhívás követ. Nincs benne ” gondolkodás “; csak azért működik megbízhatóan, mert a fordító elvégzi a típusellenőrzést fordításkor ; futás közben a generált kód bízik abban, hogy a fordító elvégezte a típusellenőrző házi feladatot. Ha nem biztonságos gipszeket használ (pl.C-stílusú mutatógörbék), akkor lehet jogszerűen kezelni a C ++ objektumokat rossz osztály objektumaként, de a nézhetőségeiket teljesen elrontják, és a kód csak elromlik.
- @tdammers Igyekeztem távol maradni az efféle választól, mert ‘ ez a fordítók megvalósítási részlete, ami lehet, vagy nem igaz néhány ezoterikus fordító esetében. A lényeg a koncepció.
- @tdammers És ” a futásidejű ” ” a program futás közben “. Nyilvánvaló, hogy a C ++ nem ‘ kezelt. De mivel megmutatta, zavart okozhat, ezért ‘ m a teljes szövegre változtatom.
Válasz
ha ismeri a funkciómutatókat, akkor ez egy példa. A definiált funkciók korai kötésnek mondhatók. míg ha a Funkciót használja, akkor a késői kötése mutat.
int add(int x,int y) { return x+y; } int sub(int x,int y) { return x-y; } int main() { //get user choice int(*fp)(int,int); //if add fp=add; //else if sub fp=sub; cout<<fp(2,2); }
itt az add és sub függvények függvények (címe a fordítási time-linkernél van lekötve)
de a függvénymutató késik Az fp megkötése a [futásidejű] felhasználói választástól függően akár addot, akár sub-t hívhat meg.
Válasz
Csak korai és késői kötés értelme van a típusok kontextusában, és nem úgy, ahogy leírja. Nagyjából minden modern nyelv olyan értelemben van beírva, hogy minden értéknek fix típusa van. A különbség akkor jön be, ha dinamikusan vagy statikusan beírt nyelveket nézünk. Dinamikusan tipizált nyelvekben a változóknak nincsenek típusaik, így bármilyen típusú értékre hivatkozhatnak, és ez azt jelenti, hogy ha valamilyen változó által hivatkozott objektumon meghívunk egy metódust, az egyetlen módja annak megállapítására, hogy a hívás érvényes-e vagy sem, keresse meg az objektum osztályát, és nézze meg, hogy a módszer valóban létezik-e. Ez lehetővé teszi néhány olyan jó dolgot, mint például új módszerek hozzáadása az osztályokhoz futás közben, mert a tényleges módszerkeresést az utolsó pillanatig halasztják. A legtöbb ember ezt a késői kötés.
Egy statikusan tipizált nyelvben a változóknak vannak típusai, és miután deklarálták, nem hivatkozhatnak olyan értékekre, amelyek nem azonos típusúak. Ez nem szigorúan igaz, de egyelőre feltételezzük. Most, ha tudja, hogy a változó csak egy adott típusú értékekre fog hivatkozni, akkor nincs ok arra, hogy kiderüljön, a metódushívás érvényes-e vagy sem futási időben, mert az érvényességet még a kód futtatása előtt meghatározhatja. Ezt korai kötésnek nevezzük.
Példa a késői kötés bemutatására rubinban:
a = 1 # a is an integer at this point a.succ # asking for its successor is valid class A def method_a # some code end end a = A.new a.method_a # this is also valid a.succ # this is not valid class A # we can re-open the class and add a method def succ # some more code end end a.succ # now this is valid
A fenti műveletsor nem lehetséges olyan nyelven, mint a Java, ahol az összes típus futás közben rögzítve van.
Válasz
Ahelyett, hogy akadémikus definíciót adnék neked, megpróbál bemutatni néhány különbséget egy valós példa segítségével a VBA használatával:
Korai kötés:
Dim x As FileSystemObject Set x = New FileSystemObject Debug.Print x.GetSpecialFolder(0)
Ehhez meg kell adni egy hivatkozást a “Microsoft Scripting Runtime” komponensre tervezéskor . Előnye, hogy hibaüzenetet kap már a fordításkor, amikor elírási hiba van a FileSystemObject
vagy a metódusnevekben, például a GetSpecialFolder
. / p>
Késői kötés
Dim x As Object Set x = CreateObject("Scripting.FileSystemObject") Debug.Print x.GetSpecialFolder(0)
Ehhez nem szükséges előzetesen megadni a hivatkozást, a példány létrehozását és típusát az elszántság csak futás közben fog megtörténni. A fordító nem panaszkodik fordítási időben, amikor megpróbál egy x
nem létező metódust meghívni, ez csak az adott sor végrehajtásakor vezet futási hibához. .
Tehát a késői kötés hátránya, hogy itt nincs erős típusa. De ez az előnye is – mondjuk, hogy van olyan összetevője, ahol több verzió létezik, és mindegyik újabb verzió további funkciókat kínál. (Valószerű példa erre az MS Office összetevője, például az Excel COM felület) A késői kötés lehetővé teszi olyan kódot írsz, amely együtt működik az összes verzióval – először meghatározhatod az adott komponens verziót, és ha kiderül, hogy csak egy régebbi verzió áll rendelkezésedre, kerüld a függvényhívások végrehajtását, amelyek nem működnek az adott verzióval. / p>
Válasz
Talán a késői kötés leggyakoribb példája az internetes URL-ek megoldása. Támogatja a dinamikus rendszereket és a nagyméretű rendszereket anélkül, hogy megpróbálná összekapcsolni és összekapcsolni a világ minden webhelyét, mielőtt elérnék bármelyiket, de másrészt futás közben némi rezsit (DNS-keresés, sokkal kevésbé IP-útválasztás) terhel.
Ebből a szempontból a nyelvi környezetekben a kötés legtöbb változata többé-kevésbé korai, fordítási vagy linkelési időben.
Mindegyiknek vannak költségei és előnyei.
Megjegyzések
- Tudna-e hivatkozást találni a kötelező érvényűség meghatározásához?Még nem hallottam az internetes címek feloldásáról ” kötésként “, bár mivel a kötés a névfeloldás, gondolom, hogy valaki azzal érvelt hogy a korai / késői kötés fogalma alkalmazható az URI feloldására az internetes címekre. De ez nem általános értelmezés, és a korai / késői kötés fogalma megelőzi azt az időpontot, amikor a számítógépeket általában az internethez csatlakoztatták.
Vélemény, hozzászólás?