Toate Google o pauză, nu pot să înțeleg. Și Wikipedia citit și, în general, orice citit. Într-adevăr eu nu înțeleg.
Ce împiedică să conectezi fișiere .cpp?
Ei bine, ai prins-l de două ori, bine, lasa compilatorul doar o singură dată și se conectează tot timpul el este un iad toate într-un singur fișier ca și în cazul în care totul se lipește împreună, astfel încât prima conexiune să fie deasupra restului și le vom vedea în partea de jos. Lăsați timp uitam modificările și recompilați schimbat numai. generează automat și atașează Lăsați fișierele header din descrierea interfeței pentru binarele pre-compilate. itp
Acesta este motivul pentru corvoada de a genera fișiere antet, nu un sistem automatizat și atribuit dezvoltator? La urma urmei, de lângă compilatorul poate genera compilate binare cu ușurință în sine descrie fișierul interfețe (care a primit fișier cpp de scanare).
Puteți conduce la o situație în care există o problemă fără utilizarea de fișiere antet? Aceasta este cea mai bună explicație.
stabilit 30 ianuarie la 05:03
Problema constă în compatibilitatea inversă.
Uite, orice nou limbaj de programare - da, chiar și Pascal, să nu mai vorbim de Java sau C # - nu au nevoie de fișiere antet. Fără îndoială, C ++, de asemenea, ar fi putut face fără ele. Care-i treaba?
Derulare rapidă înainte o jumătate de secol în urmă, în 1972. Imaginați-vă un compilator C.
Să presupunem că vrem să scrie un design compilator. Nu putem compila întregul program la un moment dat, am pur și simplu nu au suficientă memorie. Calculatoarele apoi au fost mici și lent. Dorim să compilați un pic de program de biți, câteva la un funcții de timp.
Noi ridică imediat problema modului de a compila funcția f. care se referă la o altă funcție g. Avem nevoie de o descriere separată a celorlalte funcții. Am putea, desigur, citiți toate fișierele sursă, în primul rând a determina ce caracteristici avem, și apoi citiți-le pentru a doua oară și compilați unul câte unul. Dar era prea dificil și lent, a fost necesar pentru a analiza definirea funcțiilor de două ori, și o dată pentru a arunca afară rezultatul! Acest lucru este inacceptabil consumul de timp CPU! În plus, dacă vă păstrați în minte definiția tuturor funcțiilor poate, din nou, nu are suficientă memorie.
Dennis a decis pe cine să încredințeze problema complexă a separării funcțiilor care descrie punerea sa în aplicare, și conectați numai definițiile necesare atunci când compilarea această funcție? Noi, programatorii. El a decis că ar trebui să facem pentru a ajuta compilator și funcția skopipastit definițiile într-un fișier separat și compilatorul în sine, care fișiere trebuie să definiții. (Aceasta este, primul pas de compilare este atribuit la noi.)
Acest lucru a simplificat radical compilator, dar a condus la rândul său, la problemele. Ce se întâmplă dacă am uitat să se conecteze fișierul antet corespunzător? Răspuns: o eroare de compilare. Ce se întâmplă în cazul în care sensul textului modificărilor fișier antet în funcție de orice macro? A: Compilatorul „prost“, și nu încearcă să detecteze această problemă, schimbă responsabilitatea pe noi.
La momentul de dezvoltare a limbajului a fost decizia corectă. Compilatorul va fi practic, rapid, iar programatorii nu au fost potrivnic pentru a ajuta la compilare. Ei bine, dacă cineva a făcut o greșeală, el a fost de vină.
Derularea înapoi ceasul în 1983. Bjarne creează C ++. El a decis să decoleze de pe un val de popularitate a limbajului C, și a adoptat elaborarea modelului C cu unele probleme de traducere unit'ami și direct legate de C. Cu toate acestea, prima versiune de C ++ au fost pur și simplu preprotsesoorom limbajul C! Prin urmare, problemele de compilare separate, mutat de la C la C ++. Mai rău, am adăugat noi probleme. De exemplu, șabloanele de clasă apar ca clase, dar nu generează codul obiect de la sine, așa că trebuie să meargă la trucuri și pentru a evita deficiențele de compilare separată (de exemplu, prin includerea în antetul de implementare și trucuri de legătură) sistemului.
Cu toate acestea, există un sistem de proiectare modular în C ++, care este de a ajuta programatori a scăpa de moștenirea jumătate de secol vechi. Acesta nu este încă pusă în aplicare, și în ea există complexitatea nivelului de proiectare (de exemplu, header'e a fost definit macro-uri, dacă se va vedea dacă vom trece de la header'ov la module?) Sper în viitorul dezvoltatorilor de limbi străine vor fi în continuare posibilitatea de a depăși problema inversă compatibilitate.
1), vom specifica un set de fișiere compilator CPP 2) conectați unul cu altul, folosind #include „file.cpp“ 3) în cazul în care fișierul este duplicat conexiunea el nu conectați a doua oară 4) Dacă vom compila în mod individual, apoi împreună cu binarele otkompiirovannym ar trebui automat fișier antet creat, care conține descrierea interfeței pentru a rupe din fișierul cu codul cpp. 5) de ce factorii de decizie compilatorul nu au făcut acest lucru? De ce forța mâinile pentru a genera antetele? - Maxmaxmaximus 30 ianuarie la 05:45
Acesta este motivul pentru corvoada de a genera fișiere antet, nu un sistem automatizat și atribuit dezvoltator? La urma urmei, de lângă compilatorul poate genera compilate binare cu ușurință în sine descrie fișierul interfețe (care a primit fișier cpp de scanare) - Maxmaxmaximus 30 ianuarie la 05:48
Încă o dată, citiți despre unitatea de traducere. Când compilat fișier cpp, compilatorul nu știe nimic despre celelalte fișiere compilate deja (CPP-ului în cazul în care el a avut). În ceea ce privește „corvoada de a genera fișiere antet“. De obicei, atunci când scrieți programe, în primul rând gândiți-vă la interfața (scriere .h), și apoi scrie doar punerea în aplicare (Cpp) - Krepver 30 ianuarie la 05:55
Ce împiedică să conectezi fișiere .cpp?
Lipsa lor de informații despre tipurile, accesibil din exterior.
Compilatorul convertește fișierele sursă (.c și Cpp) în fișiere obiect (.obj cusute în linker-ul într-un singur fișier .exe sau .dll.) - „semi-finite“ - „cutii negre“, importul și exportul de simboluri.
Simbolul, la rândul său, - un set de „nume de funcție / variabila - compensate de la începutul fișierului obiect.“ Importarea - această dependență fișierul obiect (nu contează în cazul în care acestea sunt puse în aplicare, doar numele coincidența cerute); export - este faptul că acest fișier este pus în aplicare.
Astfel, fișierele obiect nu conțin tipuri de date, și alte abstractii care există numai în imaginația compilator. Numai codul mașinii și datele existente într-un spațiu real, alocat RAM, și etichete de cuvinte cheie.
Din păcate, doar un nume de cunoaștere nu este suficientă pentru formarea de import (dependență). Compilatorul trebuie să cunoască structura tipurile implicate mai mult pentru a genera devierilor corecte pe stivă, se introduce apeluri suplimentare constructorilor / destructorii, efectuați conversii de tip implicite, verificați corectitudinea apelului, și așa mai departe. D.
De ce este descrierea tipurilor nu este încorporat în realizarea lor fișier obiect? Unul și același tip de date pot fi utilizate în orice număr de locuri, ci pentru că o astfel de inserție încalcă regula o definiție. Conform acestei reguli, fiecare entitate trebuie să aibă doar o singură sursă (fișierul obiect), astfel încât aspectul nu a fost incertitudinea în compararea de import și de export.
Ei bine, să compilatorul doar o singură dată și se conectează tot timpul el este un iad toate într-un singur fișier ca și în cazul în care totul se lipește împreună, astfel încât prima conexiune să fie deasupra restului și le vom vedea în partea de jos.
program de asamblare în C și C ++ se face în două etape.
Compilatorul convertește fiecare fișier sursă (.c și Cpp) la fișierul obiect (obj). În plus, fiecare fișier sursă este compilat, indiferent dacă acesta este unul din univers, și nimeni în afară de el nu mai există. În această etapă, compilatorul nu vede niciun alt fișier obiect. dar el a fost obligat să dea codul mașinii terminat. Această abordare a fost aleasă dezvoltatorii de limbi străine pentru a putea paraleliza compilație.
Linker-ul ia fișierele obiect (indiferent de modul în care și atunci când au fost primite), se leagă importul și exportul acestora și se integrează într-un singur executabil (.exe sau .dll) fișier.
Acesta este motivul pentru corvoada de a genera fișiere antet, nu un sistem automatizat și atribuit dezvoltator? La urma urmei, de lângă compilatorul poate genera compilate binare cu ușurință în sine descrie fișierul interfețe (care a primit fișier cpp de scanare).
Iată un fișier Cpp (fără includerea antetelor non-standard, au vrut să):
Compilatorul afișează această structură de clasă Logger. Și anume: ce domenii trebuie să fie în clasă și ce modificator de acces? După punerea în aplicare a unei clase pot fi distribuite în mai multe fișiere, exact ca un singur fișier poate conține punerea în aplicare a metodelor de mai multe clase.
Probabil Tu spui, „pentru a descrie logger de clasă; aici, că a fost generat de .hpp ». Și care este diferența dacă luăm în descrierea, și așa mai departe în fișierul antet?
Puteți conduce la o situație în care există o problemă fără utilizarea de fișiere antet?
și așa mai departe pentru fiecare fișier folosind Foo.
Acum, imaginați-vă că fiecare schimbare de descrieri de clase necesită înlocuire în masă în multe locuri. Uita de a stabili - compilatorul nu spune nimic, fiind greșită cu privire la programul final va cădea.
Ei bine, l-ai prins de două ori, bine, lasa compilatorul doar o singură dată și se conectează toate
Și dacă nu vreau un timp?
Asta este, presupun că este generat din cauza stiva macro de funcții similare, în cazul în care unele diferențe minore de comportament sunt determinate de alte macro-uri. Astfel. în loc de generare a codului am schimba valorile constantelor și conectați același fișier-cpp într-un alt fișier cpp-. Și vrei să nege această posibilitate?
răspunsul este dat la 30 ianuarie, la 10:13
Și vrei să nege această posibilitate? - Nu, nu vreau să fișier dacă negi acest vozmorzhnosti, după trecerea preprocesorul compilator pare schimbat sau nu, în cazul în care sa schimbat, aceasta se Lipirea a doua oară. - Maxmaxmaximus 30 ianuarie la 12:50
@Maxmaxmaximus, o opțiune interesantă. Dar eu se pare destul de scump - copac dependență și adâncimea de cuibărit poate fi foarte mare - se va mai multe controale nejustificate ale aceleași fișiere. Probabil. - Qwertiy 30 ianuarie la 14:20
@Qwertiy obține mai multe controale nejustificate ale aceleași fișiere. - Nu, pentru că chiar acum, alte limbi și aceasta operațiune nanosecundă face. MAP este pur și simplu un fișier care este generat atunci când prima compilație completă, care descrie toate versiunile fișierelor și conformitatea acestora cu unul pe altul și tot ce jazz. Și) compilatorul nu trebuie să ruleze fizic prin toate fișierele și scanați se încarcă doar fișierul MEP în RAM și de acolo toate vechi învață. Ei bine, că este un astfel de lucru ca un timp de ușor ușor în cache, și că este modul în care dispensa compilatorilor alte limbi. - Maxmaxmaximus 31 ianuarie la 00:54
@Maxmaxmaximus, în codul de mai sus ca răspuns la același fișier este inclus de trei ori (de fapt, o dată doar fișierul în sine, și apoi dublu __FILE__ #include). El nu se schimbă niciodată, dar toate de 3 ori o compilație de rezultate diferite. Ce face toate modificările recente? - Qwertiy 31 ianuarie la 09:07