ssman przyszedl, ale nie zauwazyl nic rażącego, więc 99% zostaje na miejscu, co rozmówcy na pewno zauważą:)
@wątek: Już to zostało powiedziane, mówiąc bardzo ogólnie:
A) deklaracja/declaration: to fragment, w ktorym mowisz, że "coś gdzieś będzie"
B) definicja/definition: to fragment, w którym to coś faktycznie mówisz, jak coś wygląda w środku
C) inicjalizacja/inicjalization: to fragment, w którym temu czemuś faktycznie nadajesz jakąś konkretną zawartość
D) "konkretyzacja" / instantiation - termin używany glownie przy template'ach, jest to miejsce, w ktorym 'krystalizujesz' szablon i nagle pojawia się konkretne wystapienie kodu wygenerowane przez szablon. słownik podpowiada "budowanie/stworzenie". mi takie tlumaczenie nie odpowiada, stad znaki zapytania.
E) specjalizacja - tez od szablonow.. ale to juz nie wazne, nie w temacie
A) deklaracja, deklaracja "w przód", forward declaration -- zapamiętaj ten angielski termin, a przestaną Ci się mylic.
- o to mówię, będzie kiedyś (niżej, w innym pliku .cpp, itp) funkcja X zwracająca int, biorąca jakies-tam parametry.
int X(int blah);
od tej pory, mogę wywoływać funkcję, nawet jeśli jej zawartość się nie pojawiła. najwyżej będzie błąd linkera, nie kompilacji
- o to mówię, będzie kiedyś (niżej, w innym pliku .cpp, itp) zmienna globalna Z zawierająca int
extern int Z;
od tej pory, mogę używać tej zmiennej, nawet jeśli jej miejsce fizycznego umieszczenia jeszcze się nie pojawiło. najwyżej będzie błąd linkera, nie kompilacji
B) definicja, ciało, treść, fizyczne miejsce wystąpienia. jest to polaczenie deklaracji oraz "ustalenia konstrukcji wnetrza".
- a teraz mówię, zupełnie gdzieś indziej, że funkcja X ma do parametru dodac 1 i to zwrocic
int X(int blah)
{ return blah + 1;
}
stworzylem wiec wlasnie wlasciwa funkcje. od tej pory bledy linkera jej dotyczace przestana sie pojawiac -- gdyz dopiero piszac to, ona faktycznie zaistniala w programie
- a teraz mówię, zupełnie gdzieś indziej, że Z ma byc fizycznie umieszczone tutaj, w tym module .cpp
int Z;
stworzylem wiec wlasnie wlasciwa zmienna globalna, ktora (może) zostać wyeksportowana poza moduł. od tej pory linker bedzie spinal deklaracje zmiennej globalnej INT-Z z innych modulow z tym tutaj wystapieniem
C) inicjalizacja, nadanie wartosci, nadanie tresci, sprawienie ze coś w końcu ma określoną zawartosc.
- a teraz mówię, niech Z zacznie od zawierania 15.
Z = 15;
to jest inicjalizacja, pierwotne nadanie sensu/tresci czemus tam *)
D) pomijam. kiedyś się z tym zderzysz, niech to będzie później
Niby to to jasne i proste, ale jednak uzycie ich w niektorych miejscach moze sie wydawac troche niespojnie. Na szczescie zawsze w danym miejscu znaczą jedno i to samo. A, no i w niektórych połączeniach nie mają sensu.
UWAGA: ponizej pojawiaja sie przypisy * oraz **. Pierwszy z nich nalezy przeczytac jesli nie widzi sie roznicy miedzy inicjalizacja a przypisaniem. Drugi z nich -- jesli chce sie dowiedziec o co chodzi z owa "niespojnoscia" i czemu tak wlasciwie to jej nie ma. Nie polecam czytania ** chyba, ze komus te terminy juz sie przestaly mylic i chce zeby znowu zaczely:)
-
deklaracja zmiennej globalnej - OK -- opisalem powyzej
-
definicja zmiennej globalnej - OK -- opisalem powyzej
-
inicjalizacja zmiennej globalnej - OK -- opisalem powyzej, z haczykiem
-
deklaracja zmiennej lokalnej - NIE MOŻLIWA -- napisanie "int X;" w funkcji będzie definicją. nie da się wyrazic lokalnej deklaracji zmiennej
-
definicja zmiennej globalnej - OK -- normalne "int X;" w funkcji **)
-
inicjalizacja zmiennej globalnej - OK -- normalne "int X = 5;" w funkcji **)
-
deklaracja funkcji globalnej -- OK - nazywa się je tez forward-declaration (w C++) albo prototypem (w C) albo czasem tez "sygnaturą", przyklad opisalem powyzej
-
definicja funkcji globalnej -- OK - czyli tresc, bebechy takiej funkcji, przyklad opisalem powyzej **)
-
inicjalizacja funkcji globalnej -- BEZ SENS - funkcje nie maja "zawartosci" "konkretniejszej" niz ich wewnetrzna budowa ustalona w definicji **)
-
XXX funkcji lokalnej -- f.lokalne nieistnieja. W C0x/x0 dochodzą lambdy, ale to nie to samo
-
deklaracja klasy -- OK - nazywa się je tez forward-declaration (w C++), "class X;"
-
definicja klasy -- OK - czyli tresc, bebechy takiej klasy "class X{ ..... };" **)
-
inicjalizacja klasy -- BEZ SENS - klasy nie maja "zawartosci" "konkretniejszej" niz ich wewnetrzna budowa ustalona w definicji **)
-
deklaracja członka klasy -- OK - ale jest mozliwa tylko podczas definiowania klasy "class X { ...tylkotutaj... };"
-
definicja członka klasy -- OK - mozliwa w definicji klasy, lub poza: "class X{ int bum(){return 0;}};" lub "int X::bum(){return 0;}". z kolei dla pol - tylko statycznych: "int X::iks;", dla niestatycznych - bezsensu
-
inicjalizacja członka klasy -- OK - dla metod bezsens na mocy bezsensu inicjalizacji funkcji **), dla pól mozliwa w liscie inicjalizacyjnej konstruktorow np.: " X::X() : iks(5) {....} " lub dla pol statycznych np: "int X::iks = 5;"
i temu podobne.. przypadkow wystapienia tych terminow jest wiecej, ale szczerze mowiac juz mi sie nie chce tego rozpisywac. te przyklady powinny wystarczyc do ich "zalapania".
....
A przy szablonach dochodzi jeszcze 'instantiacja' instantiation gdyz definicja szablonu nie jest rownoznaczna z definicja jakiejkolwiek klasy. Nawet specjalizacja szablonu nie koniecznie prowadzi do niej, tylko tworzy nową, pochodną definicję innego, bliźniaczo podobnego szablonu.. Niesamowicie specyficzne miejsce, w którym nagle na podstawie definicji szablonu kompilator tworzy automatycznie faktycznie jedną lub więcej definicji jednej lub więcej klas opisanych tym szablonem - nazywa sie "instantiation"/wywolaniem/wystapieniem/konkretyzacją/krystalizacja/(..). Miejsca te moga byc "implicit" lub "explicit". Te pierwsze sa 'automatyczne', po cichu, i zapominamy o tym ze w ogole istnieja, np. "vector<int> tabelka;". Te drugie sa napisane wyraznie przez programiste, z jakiegos zawilego powodu. Np: "template std::vector<int>;" - nakazuje kompilatorowi wygenerowac taka definicje klasy (vector-po-int) nawet jesli kompilatorowi wydaje się ze zaden kod jej nie uzywa.. Teraz to skojarz z wielomodułowościa, czyli 50cioma plikami .cpp i .hpp, możliwościa kompilacji plików .cpp do modułów .o/bibliotek .a lub .lib/bibliotek dynamicznych .so lub .dll/itp i może już przeczuwasz gdzie czasem tego trzeba użyć i czemu czasem "wygenerowany ale nieuzywany" jest potrzebny..
*) Inicjalizacja różni się przypisania 'tylko' LOGICZNIE: jesli zdefiniujesz zmienna mozesz czesto natychmiast jej nadac wartosc w tej samej linii. bedzie to linijka z "definicja i inicjalizacja", wszystkie nastepne z=1111 to beda juz tylko zwykle przypisania. Jesli jej nie nadasz wartosci w tej samej linii, tylko pozniej, to linijka ta będzie tylko definicją, zmienna będzie stworzona jako niezainicjalizowana. Pozniej, pierwsze przypisanie z=444 na ktore program trafi zainicjalizuje ją, ale NIE bedzie inicjalizacja. Bedzie to zwykle przypisanie, ktore "naprawi" niezainicjalizowana zmienna.. "LOGICZNIE", myślowo, o takim miejscu tez sie mowi ze jest to inicjalizacja zmiennej Z, gdyz jest to pierwsza jej sensowna wartosc, jednak faktycznie tak nie jest. Zmienne mozna zdefiniowac-i-inicjalizowac, albo zdefiniowac-bez-inicjalizacji a potem przypisac im nowa wartosc.
**) niby-niespojnosc. "deklaracja" funkcji mowi o jej wygladzie zewnetrznym (typ, nazwa), "definicja" o wewnetrznym (kod), inicjalizacji brak. dla zmiennych, "deklaracja" mowi o jej wygladzie zewnetrznym (typ, nazwa), "definicja" o miejscu wystąpienia, a inicjalizcja nadaje wartosc.. Funkcja nie ma swojej wartosci? A 'miejsce wystapienia' to jej kod? niespojne nazwy definicja-inicjalizacja?
Otóż, wszystko się zgadza, tylko zostało źle opisane, gdyż piszac to patrzylem ze zlej strony.. Nazwy te zostaly ukute dla zmiennych, i dla funkcji tez pasuja idealnie, tylko nalezy spojrzec od strony kompilatora i linkera. Wartością funkcji, jest jest kod. Miejsce w ktorym piszesz cialo funkcji jest miejscem jej definicji-i-inicjalizacji. Definicji, gdyz kompilator tworzy kod wtymmodule, czyli to jest jej wystapienie. Inicjalizacji, gdyz natychmiast ta funkcja dostaje konkretna zawartosc - swoj kod. Ot, roznica miedzy nimi z zmiennymi globalnymi w tym, ze sa wywolywalne i nie-przypisywalne. Raz "zainicjalizowanej" funkcji nie zmienisz na nowa. Kod zawsze tam zostanie niezmieniony. W kazdym bądz razie, tak jakby. Mozna "inicjalizacje funkcji" luzno skojarzyc przez kontrast z purevirtual czyli metodami-bez-tresci..
analogiczna uwaga tyczy sie klas z tym ze... nalezy uwazac, gdyz definicja-i-inicjalizacja klasy postaci "class X{ int bumbum(); int iks; };" jest ustaleniem się wnetrza klasy ale ... nie robi nic. A dokladniej, robi deklarację metody 'bumbum' oraz deklaracje pola iks. Dopiero zapis: "class X{ int bumbum() {return iks+1;} int iks; };" faktycznie cos by zdefiniowal -- metodę "bumbum". Pole 'iks' dalej jest tylko zadeklarowane, nie ma ono zadnego fizycznego miejsca dla siebie... Dopiero gdy stworzysz OBIEKT tej klasy, to to pole faktycznie zaistnieje..
//edit: widze, ze tak dlugo to pisalem, ze az juz sie dyskusja skonczyla:) no coz, moze komus sie przyda potem:)
//edit2: Fanael podsunał mi tłumaczenie instantiation->konkretyzacja. IMHO troche za łatwe do pomylenia ze specjalizacją, ale wierze na slowo gdyz sam nie pamietam i ciagle uzywam angielskiego terminu:)