Indekso |
Klasoj
Estas du kategorioj de datumtipoj utila en C + + estas klasifikitaj kiel bazaj tipoj kaj tipoj difinita de la programisto.Ĝuste kiel en C, oni povas difini datumoj engaĝante kombinaĵoj de la bazaj tipoj, tiuj tipoj estas nomitaj strukturoj (structs). C + + alportas novajn datumojn reprezento, tre simila en formo al la strukturoj, sed malsama en koncepto formo: la klaso ŝlosilvorto, kiu estas uzita por krei pli riĉan klaso de objektoj kiuj structs. Kiam vi deklaras ensalutilo, kiel kiam ni deklaras variablon en loko de tipo especifiquemos klaso kreos objekto.
Antaŭ ol ni daŭrigos, vidu iom sur la koncepto malantaŭ la uzo de celoj. Objekto estas komprenita kiel ento datumojn en memoro kiu esence devas esti respondeca por ilia enhavo, te, objekto devas povi memstare administri siaj enhavo, aŭ havigi aliaj rimedoj de kodo entoj fari ĝin tiel sekura.
Origino (atributoj)
Observi, ekzemple, jena kodo:struct MyData {Mez n; char datumoj [10]; nReal kaleŝego; };
Membro funkcioj (metodoj)
Nun supozu ni starigis kiel maniero por eniri kaj alia por legi datumoj matrico:struct MyData {Mez n; char datumoj [10]; nReal kaleŝego; write_data bool (int post, char c) {Se (post> = 0 && post <10) {Datumoj [post] = c; revenu vera; } revenu falsa; } char read_data (int post) {Se (post> = 0 && post <10) {Reiri datumoj [post]; } revenu '\ 0'; } };
Koncepto
La problemo de publika videbleco de datumoj en strukturo povas esti solvita per unu el la konceptoj de celoj, encapsulación. Encapsular datumoj, signifas rezervante aliron al funkcioj kiuj estas ene de malgranda grupo, specialigita operacioj tia manipulado de datumoj. Unu avantaĝo de ĉi tiu proceduro estas, ke la kodo ricevas pli organizita formato, kie la procezoj fariĝis klare distingaj, se ni devas analizi la kodo, ĉiu proceduro estos limigitaj al partoj difinita por ĉiu operacio.Deklarante klasoj
La strukturoj estas tre similaj al klasoj, kun malmulta diferenco, ni prenu la kazon de pasi strukturoj kiel funkcio argumentoj:# Inkluzivi <iostream> # Inkluzivi <string> # Ifndef Win32 / / En kazo ĝi ne estas programado en Vindozo # Inkluzivi <conio.h> / / estos inkluzivita en la biblioteko conio.h # Endif / / permesante uzo getch () anstataŭ sistemo ("paŭzo"); uzante nomspaco std; klaso Persono { kordoj nomo; int alteco; }; void setValues (Person &); void getValues (Person const &); int main () { Persono p1; setValues (p1); cout << "Enirante datumoj sur la persono: \ n"; cout << "================================ \ n"; getValues (p1); # Ifdef Win32 sistemo ("paŭzo"); # Else getch (); # Endif revenu 0; } void setValues (Person & pers) { cout << "Tajpu la persono nomo:"; getline (cin, pers. nomo); cout << "Tajpu la alteco en milimetroj:"; cin >> pers. alteco; cin. ignori (); } getValues void (const Persono & pers) { cout << "Nomo de persono" << pers. nomo << endl; cout << "La persono alteco en milimetroj estas:" << pers. alteco << endl; }
- Ni ŝanĝis la struct ensalutilo por klaso
- Sed se ni provos traduki la programo kaŭzos kompili erarojn, ĉar ni havas nun membro variabloj kiuj estas privataj implicite, tiuj ne estas vidita de funkcioj ekster la klaso.
Post unu klaso povas difini malsamajn modojn de videbleco de variabloj kaj funkcioj.
La proceduro povas esti:
- privataj (nur povas konsenti por membroj de la sama klaso)
- publika (povas aliri ekster la objekto kie estas metita)
- protektitaj (forlasi tiun cxar kiam ni parolas pri derivaĵoj klasoj, ĉar dependas de tiu koncepto).
Best imagis en tabular formo:
|
|---|
# Inkluzivi <iostream> # Inkluzivi <string> uzante nomspaco std; klaso Persono { privata: kordoj nomo; int alteco; publika: kordoj getName () const; void setName (linio); int getHeight () const; void setHeight (int); }; Persono :: string getName () const {Reveno nomo;} void Persono :: setName (string j) { if (s. length () == 0) nomo = "Neniu nomo atribuita"; alie nomo = s; } int Persono :: getHeight () const {Reveno alteco;} void Persono :: setHeight (int h) { se (h <0) alteco = 0; alie alteco = h; } void setValues (Person &); void getValues (Person const &); int main () { Persono p1; setValues (p1); cout << "elirigi persono datumoj \ n"; cout << "====================== \ n"; getValues (p1); revenu 0; } void setValues (Person & pers) { string str; int h; cout << "Tajpu la nomo de persono:"; getline (cin, str); pers. setName (str); cout << "Enter alteco en milimeters"; cin >> h; cin. ignori (); pers. setHeight (h); } getValues void (const Persono & pers) { cout << "Persono nomo:" << pers. getName () << endl; cout << "Persono de alteco en milimeters estas:" << pers. getHeight () << endl; }
Nun ke "Persono" estas klaso membro funkciojn povas okupi datumoj validación antaux atribui valorojn al variabloj. Ni povus fari la setName funkcio por kontroli ĉu la enigo kordoj devus esti malplena kaj se ĝi estis, metis defaŭlta valoro kiel "anonima". simile oni povis havi "setHeight" por kontroli ke enigo valoroj lokus kaj se ili estis negativa, metis nulo, aŭ ne realigi agon.
Ĉiuj de ĉi tiuj karakterizaĵoj pruvi la koncepton de encapsulación. Lia celo estas fari la kodon pli modularized, restriktante la medio de analizo al partoj de klare difinita programoj. Pro tiu koncepto povas havi kodojn facile analizi kaj subteni.
Instantiating objektoj
Objekto instantiation estas la procezo de kreado la logika strukturo de la sama memoro. Tio okazas kiam ni deklaras la celojn, ĉar nun la tuta procezo de konstruo estas la sama efiko. Do, ĉiufoje kiam ni deklaras objekto instantiating ĝin, te, ni kreas petskribo de la klaso.Ni povas deklari la celoj starigis baldaŭ post la klaso kiel povas vidiĝi en Kazo 1 sube. En ĉi tiu kazo ni kreis variablo kiel objekto rect kiel establita de la modelo difinita de la klaso ŝlosilvorto. Tiu tipo de frazo estas pli kutima por celoj kreis tutmonde, ĉar la inkludo de tiu deklaro en la kaplinio povas havi plurajn objektojn estas kreitaj kun la sama nomo kiel la kaplinio estas alvokebla multnombraj arkivoj. Sekve, estas pli singarde uzu tiun opcion kiam la propozicio estas en la fonto dosiero kaj ne en la kaploko.
1-a kazo:
klaso CRectangle { int x, y; publika: set_values void (int, int); int areo (void); Rect};
2-a kazo:
klaso CRectangle { int x, y; publika: set_values void (int, int); int areo (void); }; int main () { CRectangle rect; }
En ambaŭ kazoj ni havas
|
|---|
Por pli bone kompreni tiun koncepton povas fari analogion. Konsideri objekto rezisto: ni scias ke ni devas uzi ĝin kaj ŝi devas havi iujn trajtojn, tiam ni havi lian valoron en omoj, maksimuma povo, toleremo, inter aliaj, kaj havas funkcion kiu donos al ni la fluo kiu pasas tra ĝi kiam ni aplikas elektran tension. Ni ne bezonas scii kio estas farita, aŭ kiel tiuj internaj karakterizaĵoj faras funkcii, nur preni ni la rezultojn.
Prenu la ekzemplon:
Nun ni montras ke ni povas havi membron funkcioj nur kiel prototipoj kaj starigis ilin ekster klaso. CXar ni uzas la scoping operatoro :: kiu difinas la kodo situo kie estas identigilo en la formato: Medio :: Scope :: funkcio aŭ donita. Ĝenerale, kiam ni deklaras ensalutiloj ene de la klaso povas difini ilin en la tutmondan medion per referenco tiuj scoping operatoro.
/ / Ekzemplo klasoj # Inkluzivi <iostream> uzante nomspaco std; klaso CRectangle { int x, y; publika: set_values void (int, int); int areo () {return (x * y);} }; CRectangle set_values :: void (int a, int b) { x = al; y = b; } / / Atentu la "::" kiu pemite ni difini la klaso membro funkcio ekster la klaso CRectangle int main () { CRectangle rect / / difini klaso objekto rect. set_values (3, 4) / / Membro objekto cout << "areo:" << rect. Areo (); sistemo ("paŭzo"); revenu 0; } / / Ekzemplo klasoj # Inkluzivi <iostream> uzante nomspaco std; klaso CRectangle { int x, y; publika: set_values void (int a, int b) { x = al; y = b; } int areo () {return (x * y);} }; int main () { CRectangle rect / / difini klaso objekto rect. set_values (3, 4) / / Membro objekto cout << "areo:" << rect. Areo (); sistemo ("paŭzo"); revenu 0; }
Areo: 12
La antaŭa ekzemplo esploras karakteriza de ĉiuj fermitaj geometria figuro havanta internan areon. Notu ke ĉi maniero difini la klaso lokoj kalkuli la areo ene de la difino tio.
Ĉi tiu modo kaŭzas la kodo esti nur unu modelo, la tasko de kalkulanta
la areo ne estos kreita se ne uzita dum la skribo de la resto de la
programo. Preni alian ekzemplon:
klaso Hundo { publika: setAge void (int aĝo); getAge int (); setWeight void (int pezo); getWeight int (); neniigas paroli (); privata: int aĝo; int pezo; }; void Hundo :: setAge (int aĝo) { ĉi -> aĝo = aĝo; } Hundo getAge :: int () { revenu aktoj; } Hundo setWeight :: void (int pezo) { ĉi -> pezo = pezo; } Hundo getWeight :: int () { revenu pezo; } void Hundo :: paroli () { cout << "Bark" << endl; }
Difino de klasoj
Vi uzas la vorto "klaso" por krei klason, sekvis tiam la nomo kiun vi volas doni ĝin kaj fine opcio la sama krampoj.La difino enhavas:
- datumoj (propraĵoj);
- metodoj (membro funkcioj)
Unue demandu kion estas necesa por savi bildon, tiam kia manipuladoj bezonas.
La bildo estas 400 rastrumeroj larĝa kaj 300 rastrumeroj altaj. Ĉiu pixel havas la propraĵoj de koloro kaj bildo. La koloro komprenas ruĝa, blua kaj verda, sur skalo de 0 al
Nun ni planas metodoj. Unue, ni supozu, ke ni havas la limigon de <= 400 rastrumeroj, kaj tiujn valorojn estos farita de la konstruilo por krei la objekton. Ni ne bezonas metodojn por kondiĉas la alteco kaj larĝeco, sed ni bezonas por akiri kaj legi la valoroj. Tiu strategio ankaŭ helpos al ni subtenas la valorojn de donita pixel kaj lia loko.
La unua versio devus tiam esti:
{Dosiero klaso publika: int getWidth (); int getHeight (); void setX (int x); int getX (); setY void (int y); getY int (); setRed void (duobla ruĝa); getRed duobla (); setBlue void (duobla blua); getBlue duobla (); setGreen void (duobla verda); getGreen duobla (); privata: int _width; int _height; int _x; int _y; duobla _red [400] [400]; duobla _blue [400] [400]; duobla _green [400] [400]; isWithinSize bulea (int j); clipIntensity duobla (double brilo); };
Aliro Specifiers
- Ni rezervis vortoj privata kaj publika - nomiĝas aliro specifiers.
- privata - Indikas gamon de variabloj aŭ funkcioj kiuj povas aliri nur por membroj de la klaso, do neniu ekster la alia kodo povas aliri ilin;
- publika - Indikas gamon de variabloj aŭ funkcioj kiuj povas aliri per iu kodo en la programo, kaj por la internaj funkcioj de la klaso ne necesas specifi la objekto dum por la aliaj partoj de la programo estas necese precizigi la celo al kiu ili apartenas .
La pako celas unuavice du celojn:
- Forigi la bezonon por kono de la interna strukturo por tiuj, kiuj deziras uzi ĝin. Ekzemple, se la celoj devas subteni la aron de kvar bajtojn, tio povas esti atingita per uzo du variabloj mallongaj int, int unu, vektora kun kvar characteres, aŭ variado de iu el la antaŭa sensigna, sed ĉi tiuj detaloj estas ne bezonas esti elmontrita.
- Se la interna reprezentado de datoj estas modifita, kondiĉe ke la reveno tipoj kaj parametrojn de la publikaj funkcioj restas neŝanĝita, ni ne bezonas ŝanĝi kodo uzanta klaso celoj.
Se neniu aliro specifier uzas, ĉiuj membroj kaj metodoj estas deklaritaj privatajn defaŭlte.
Estas du metodoj por difini la membro funkcioj:
- Ili povas esti difinita ene de la klaso, kiu estas taŭga por malgrandaj funkcioj;
- Kaj ĉefaj funkcioj povas esti difinita ekster la klaso.
Fabrikantoj
Koncepto
La konstruantoj "constructores" estas membro funkcioj (metodoj) de speciala klaso. Permesu inicialización de membro variabloj de objekto. Aŭ pli ĝuste, permesi la konstruon kaj inicialización de objekto klasoj. Se vi ne deklari la tradukilo faras ĝin por ni. La konstruantoj ĉiam havas la saman nomon kiel la klaso.Objektoj estas konstruitaj tra tiuj specialaj funkcioj nomataj constructores. Ĝis nun ne deklari estis kreitaj aŭtomate. Ĉi tiuj funkcioj havas iujn karakterizaĵojn kiuj faras ilin malsamaj de normala, kiu ebligas al ili konstrui la logika strukturo de la originala objekto. Tiel tiuj funkcioj estas funkcioj de objekto orientiĝo kaj servi por krei ilin.
Constructores ne povas nomi eksplicite kiel ni faras en la kazo de funkcioj regula membro. Ili estas nur ekzekutita kiam nova objekto de la klaso estas kreita. Sekve, estas nur unu okazaĵo eblas ekzekuti constructor, la celo instantiation.
La ĉefaj karakterizaĵoj de la konstruistoj estas:
- Ne havas ajnan tipon de reveno;
- Ne povas esti interpretita de eksplicita alvoko en la kodo;
- Kuru tuj post la baza tipo de objekto estis kreita;
- Pravalorizi datumojn valoroj kiuj la objekto bezonas por komenci funkciadon konvene.
Deklaro
Ni povas facile krei constructores, tra la trajtoj kiuj distingas ilin de kutima membro funkcioj. Tio estas, ni difini funkcion membro kiu havas la saman nomon kiel la klaso, ne revenis tipo kaj deklari kiel publika do ĝi povas esti aliritaj ĉiu kiu volas instantiate celoj. Ni vidu kiel difini constructor:Plumo klaso {String koloro; int volumo; / / / / / / / / / / / / / / / publika: Plumo (string c, int v); }; Plumo :: Plumo (string c, int v) {Koloro = c; v = volumo; }
Plumo klaso {String koloro; int volumo; / / / / / / / / / / / / / / / publika: Plumo (string c, int v): koloro (c), volumo (v) { } };
Destructors
Koncepto
Krom la konstruilo lingvo C + +, kaj aliaj objekteman lingvoj, havas malsaman tipon de papero speciale kreita kaj prizorgata de la lingvo, la destructors. Ĉi tiuj estas desegnita por malmunti la strukturo de la objekto kiam fermanta suben. The Detrua havas la saman nomon kiel la klaso, sed antaŭita de la signo supersigno "~" kaj ankaŭ revenas sen valoro.The Detrua havas la sekvajn trajtojn:
- The Detrua nomas kiam la objekto estas finita;
- Ĝi estas uzata por liberigi ajna memoro kiu estis atribuitaj;
Deklaro
Lasu la Hundo klaso kun constructor kaj Detrua.klaso Hundo { publika: Hundo () / / Constructor ~ Hundo () / / Detrua setAge void (int aĝo); getAge int (); setWeight void (int pezo); getWeight int (); neniigas paroli (); privata: int aĝo; int pezo; }; Hundo Hundo :: () { aĝo = 0; pezo = 0; cout << "Constructor Called Hundo" << endl; } Hundo :: ~ Hundo () { cout << "Detrua Called Hundo" << endl; }
- Constructor havas la saman nomon kiel la klaso;
- The Detrua havas la saman nomon kiel la klaso kun la prefikso supersigno "~";
- La konstruisto estis uzita por pravalorizi la membro variabloj, sed aliaj ekzemploj povus rezervi memoron rimedoj por proprigi aparatoj kaj realigi sistemon inicialización kodo;
- The Detrua en la ekzemplo neniel reala ago, krom aserti ke la eĥo estis nomita.
"kopio constructores"
Al "kopio constructor" estas speciala konstruilo kiu prenas kiel argumento referenco al objekto de la sama klaso kaj kreas novan objekton kiu estas kopio de la objekto referenco. Defaŭlte, la tradukilo proponas "kopii constructor" kiu faras la membro de membro kopion de la originala objekto, konstrui identa objekto. Tiu nomiĝas "malprofunda kopio" aŭ "membro saĝa." En iuj situacioj kopion de objekto estas ne kontentiga por vidi ke ni vidos la oficisto klaso, sube:# Inkluzivi <iostream> uzante nomspaco std; klaso Oficisto { publika: Dependa (char * nomon, int id); ~ Oficisto (); char * getName () {reveno _name;} privata: / / Aliaj metodoj Accessor int _id; char * _name; }; Oficisto :: Oficisto (char * nomon, int id) { _id = iru; _name = new char [strlen (nomo) + 1]; / / allocates tabelo objekto karaktero strcpy (_name, nomo); } Oficisto :: ~ Oficisto () { forviŝi _name; } int main () { Oficisto programisto ("John", 22); cout << programisto. getName () << endl; revenu 0; }
La strcpy funkcio aŭtomate aldonas la nula Terminator string destino.
Ankaŭ rimarku ke la Detrua liberigas la memoro uzata por stoki la oficisto nomo, por eviti memoro fugo.
Nun imagu ke john estas promociita:
int main () { Oficisto programisto ("John", 22); cout << programisto. getName () << endl; / / Multaj kodo .... Oficisto direktisto (& programisto); / / Kreas novan Oficisto "direktisto" / / Kiu estas la ekzakta kopio de la / / Oficisto "programisto". revenu 0; }
Ni havas du punteros ambaŭ enhavas la sama adreso. Imagu nun ke nova oficisto dungita. kiam la nomo estas ĝisdatigita, ni ne nur ŝanĝi la nomon de la oficisto, sed ankaŭ la direktisto. Fine, kiam objektoj estas ne plu uzata kaj la Detrua de la klaso faras la liberigo de libera memoro spaco provu dufoje al la sama adreso, kaŭzante eraro en la sistemo de dinamika memoro atribuo, kio devigos la mastruma sistemo por forigi la programon la memoro.
Por solvi tiun problemon ni difini kopion konstruilo ("kopio constructor") en la klaso, anstataŭante la defaŭlta efektivigo de la tradukilo. Ĉi tiu funkcio estas aŭtomate identigita kaj kaŭzas la tradukilo ne kreas lian version de la konstruilo. Do, difini kopion konstruilo mem estas la plej efika maniero kiam nia celojn teni trajtojn kiuj faras ilin malsamaj de la defaŭlta.
Por krei la konstruanto simple difini ĝin en la klaso:
# Inkluzivi <iostream> uzante nomspaco std; klaso Oficisto { publika: Dependa (const Oficisto & e); Dependa (char * nomon, int id); ~ Oficisto (); char * getName () {reveno _name;} privata: / / Aliaj metodoj Accessor int _id; char * _name; }; Oficisto :: Oficisto (const Oficisto & e); { _id = e._id; _name = new char [strlen (e._name) + 1]; / / allocates tabelo objekto karaktero strcpy (_name, e._name); }
Nenhum comentário:
Postar um comentário