Osztályok és objektumok
Felhívjuk figyelmét, hogy amennyiben leírjuk a test egy módszer. mod () és a védelem () vannak leírva együtt testüket közvetlenül belül a szerkezet. De meg tudod csinálni egyébként: hogy az eljárás prototípusok a szerkezeten belül, és a szervezet működésében definícióval - a szerkezet, mint mi a „+” operátor.
Az első módszert használják a rövid és egyszerű módszereket, amelyek várhatóan már nem változik. Így jön részben az a tény, hogy a leírás az osztályok általában helyezni a fejléc fájlok később az alkalmazás segítségével, az #include direktíva. Ezen túlmenően, ez a módszer gépi utasításokat a fordító által generált elérésekor ezeket a funkciókat közvetlenül be a lefordított szöveget. Ez csökkenti a költségeit azok végrehajtása, a végrehajtás az ilyen módszerek nem jár a függvényhívás és visszahúzó szerkezettel rendelkeznek, növekvő viszont a méret a futtatható kódot (azaz az ilyen eljárások inline vagy beágyazott). A második út az előnyös komplex módszerek. Nyilvánították, így a funkció automatikusan helyébe a fordító a szubrutin hívás, de ha hozzá a kulcsszót inline lehet helyettesíteni a szövegben, mint az első esetben.
Emellett a fent említett módszerrel, a létrehozása a beágyazott funkciók (a módszert írt közvetlenül a szervezetbe szerkezet), van egy másik módja - helyezze specifikáló inline meghatározás előtt módszer:
inline _3d _3d :: operator + (_3d b)
_3d c;
c.x = x + b.x;
c.y = y + b.y;
c.z = Z + b.z;
vissza c;
>
Most az üzemeltető „+” lesz ágyazva a funkciót.
Beépített függvények majdnem ugyanaz, mint a makró paraméter, de számos előnnyel az utóbbi. Először is, inline módszerrel a karcsúbb módszer beágyazó program rövid funkciót. Másodszor, a C ++ fordító sokkal jobb dolgozni beágyazott funkciók, mint a makró.
Fontos megérteni, hogy inline nem parancs a fordító, hanem egy kérés, hogy egy beágyazott módszer. Ha valamilyen okból (például jelenlétében a hurok szereplők funkció, kapcsoló vagy goto) fordító nem felel meg a kérést, akkor a funkciót kell összeállítani, mint egy non-jeit.
Konstruktorok és a destruktor
_3d vectorA;
kettős m;
vectorA.x = 17,56;
vectorA.y = 35.12;
vectorA.z = 1,0;
m = vectorA.mod ();
Szerint azonban a tanait OOP ilyen programozási stílust kell tekinteni, téves, mert elméletileg az elemeket, melyek állapotát írja le egy tárgy kell rejtve, és csak csak küldött üzenetek objektumot. Ha megváltoztatja az osztály definíciója korábban adott _3d a következő:
megkapjuk az „ideológiailag írástudó” megoldás. De amikor fordítod az előző műsorszám lesz diagnosztizáltak, hogy megkísérelje elérni a védett osztály tagja. Ez nagyszerű, mert akkor teszik, hogy kiegészítse az osztály interfész módszerek, akkor értékeket rendelhet a koordinátákat a vektor.
A következő változat az osztály a következőképpen nézhet ki:
set () módszer lehetővé teszi, hogy hozzá néhány kezdeti értékeit a koordinátákat a vektor (és csak ez a módszer!).
Egy másik megjegyzés: bár az X, Y és Z besorolása védett egy olyan csoportjának tagjai, egyértelmű fellebbezést ezeket az elemeket a átadott objektumot, mint a paraméter (.. Lásd a nyúlvány () módszer és a „+”), hogy továbbra is lehetőség.
Konstruktorok C ++ neveket, amelyek megfelelnek az osztály neve. A kivitelező lehet a felhasználó által megadott, vagy a fordító generál az alapértelmezett konstruktor. A kivitelező lehet hivatkozni explicit vagy implicit módon. A fordító automatikusan felhívja a megfelelő konstruktor, ahol meghatározhatja az új objektum osztály. Tervező nem ad vissza semmilyen értéket, és nem használja a kulcsszó űrt a tervező leírást.
A funkció a kölcsönös kivitelező, destruktor. Ez a funkció általában meghívásra, ha egy objektum törlésre kerül. Például, ha létrehoz egy objektumot dinamikusan memóriát érte, meg kell szabadítani, ha az objektum törlődik. Helyi kerül eltávolításra, amikor kimennek a hatálya alá. Globális objektumok törlődnek, amikor a program véget ér.
C ++ destruktorai neve "
class_name. „Like a kivitelező, a romboló nincs visszatérési értéke, de ellentétben a kivitelező nem nevezhető kifejezetten. A konstruktor és destruktor nem írható le zárt osztály részét képezi.
_3d :: _ 3d () // konstruktor _3d
x = y = z = 0;
cout <<'Работа конструктора _3d \n';
>
main ()
_3d A; // létrehozni az objektumot A és inicializálja annak elemei
// A.x = A.y = A.z = 0;
A.set (3.4.0); // Most A.x = 3,0, A.y = 4,0, A.z = 0,0
cout <
Az eredmény a program:
Work _3d tervező
5.0
Work destructor _3d
Kits paraméterekkel és túlterhelés tervezők
osztály _3d
double x, y, z;
nyilvános:
_3d ();
_3d (dupla initX, dupla initY, kettős initZ);
.
>;
_3d :: _ 3d (dupla initX, dupla initY, dupla initZ)
// konstruktor paraméterekkel _3d
X = initX;
y = initY;
Z = initZ;
cout <<'Работа конструктора _3d \n';
>
main ()
_3d A; // létrehozni az objektumot A és inicializálja annak elemei
// A.x = A.y = A.z = 0;
A.set (3.4.0); // Most A.x = 3,0, A.y = 4,0, A.z = 0,0
_3d B (3.4.0); // létrehozunk egy objektumot a B és inicializálja annak elemei
// B.x = 3,0, B.y = 4,0, B.z = 0,0
>
Az ilyen módon hívja a kivitelező a rövidítés kifejezések
Ezzel szemben a kivitelező, destruktor lehet paramétereket. Ez érthető, hiszen nincs paraméter átadással mechanizmus eltávolítja az objektumot.
Ebben a példában ez könnyű megérteni, mi oka lehet annak szükségességét, hogy a túlterhelés konstruktőrök. Ez egy túlterhelés, hiszen beszélünk funkciókat, amelyek az azonos nevű, de eltérő paraméter listákat. A fő értelme a túlterhelés konstruktőrök az, hogy a programozó a legmegfelelőbb objektum inicializálása módszert.
A mi példánkban, a leggyakoribb változat túlterhelés konstruktőrök, azaz kivitelező paraméterek és kivitelező paraméterekkel. Normális esetben, a programban vannak szükség mindkét faj, a paraméterek, mint kivitelező sokkal kényelmesebb, ha dolgozik, egyetlen tárgy, de nem lehet használni inicializáláskor a dinamikus objektum tömb elemei (a statikus tömb).
Bár kivitelező is túlterhelt, ahányszor csak akar, akkor jobb, ha nem használják ki azt. Tervező ne terhelje túl csak a leggyakoribb helyzetekben.
hozzárendelése tárgyak
osztály ClassName1
int a, b;
nyilvános:
void set (int ia, int ib)
>;
osztály ClassName2
int a, b;
nyilvános:
void set (int ia, int ib)
>;
Ahhoz, hogy egy kísérlet elvégzésére
ClassName1 c1;
ClassName2 c2;
c2 = c1;
Ennek eredményeként a program, hogy „c2.b = 111”, ahelyett, hogy 11, mint várták.
A túlterhelt értékadó operátor
Ahhoz, hogy elkerüljük az ilyen félreértések, az értékadó operátor túlterhelt, amely kifejezetten leírt (azaz szabályozott) folyamat hozzárendelése adatelemek egy tárgy a megfelelő elemek egy másik adat objektum.
De ahogyan azt most meg a mi például háromdimenziós vektor.
Naivitás lenne azt feltételezni, hogy minden egyes új típusú változó _3d egy másolatot készít a függvény, amely végrehajtja a szolgáltatók „+” és „=”. Minden funkció miatt egy példányban, és hívja a folyamat, mely során egy rejtett paraméter - a mutatót az esetben a változó, amelyre azt kiadták. Ezt az indexet ezt a nevet. Ha a változó írja le a függvény nem globális, úgy véljük, hogy ez egy tagja a szerkezet, és tartozik a munka változó ezt. Ezért a végrehajtási az üzemeltetők mentünk le az utat, hogy a következő területeken: a szerkezet, amelyre az üzemeltető fogják hívni.
Az érvek funkciók szereplők járnak operandusok és a visszatérési érték - alkalmazásának eredménye az üzemeltető. Különösen az üzemeltető „=” szükséges ahhoz, hogy szekvenciális hozzárendelés (a = b = c). Binary szereplők egy érv - a második mutató átengedjük ezt. Egyoperandusú, illetve egy - ez.
Transzfer a funkciók és a visszatérés a tárgy
Tárgyak átadhatók funkcionál érveket ugyanúgy, mint más típusú adatok továbbítása. Mindezek a már használt, amikor végre módszerek klassa_3d. ahol a paraméterek a vetítési technikák (.), operátor + (.) és operator = (.) telt objektum típus _3d.
Emlékeztetni kell arra, hogy a C ++ paraméterátadási eljárás, az alapértelmezett átadása tárgyak értékét. Ez azt jelenti, hogy a függvény létrehoz egy másolatot a tárgy - egy érv, és ezt a példányt, nem maga a tárgy, használja ezt a funkciót. Ezért az az objektum másolatának változások függvényében nem érintik magát a tárgyat.
Ha egy objektum át a függvényeknek van egy új objektumot. Ha a kilépési munka, ami átkerült a tárgy befejeződött, a másolatot az érv eltávolítjuk. És ez az, amit meg kell figyelni itt. Milyen a másolatot a tárgy és a tárgy destruktor érvényesíthető, ha amikor levette a példány? Az a tény, hogy egy példányt a destruktor nevezik, talán érthető, hiszen a tárgy (egy példányát az objektum, amely átadva paraméterként) megy ki a hatálya alól. De ne feledjük, hogy az objektum a függvény belsejében - Bit-bölcs, hogy egy példányt a telt tárgyat, ami azt jelenti, hogy ha az objektum tartalmaz, például egy mutatót néhány dinamikusan allokált memória területet, amikor a másolás egy objektum jön létre, rámutatva, hogy az azonos memóriahely. És amint a destruktor nevezik ki, amelyek általában vett, hogy kiadja a memóriát, a felszabadított memóriaterület mutatott az entitás az „eredeti”, ami a pusztulását az eredeti objektumot.
osztály ClassName
nyilvános:
ClassName ()
cout <<'Работа конструктора \n';
>
ClassName ()
cout <<'Работа деструктора \n';
>
>;
void f (ClassName o)
cout <<'Работа функции f \n';
>
Ez a program a következő fog történni
tervezési munkák
Munka f
munka destructor
munka destructor
Az építtető csak egyszer hívja. Ez akkor fordul elő, amikor létrehoz c1. Azonban, a romboló váltja kétszer, egyszer a másolat o. másodszor az objektum c1. Az a tény, hogy a destruktor neve kétszer lehetne a potenciális problémák, például a tárgyak destructor kiadások dinamikusan lefoglalt memória terület.
Hasonló probléma merül fel, ha az objektumot a visszatérési érték.
Annak érdekében, hogy működjön is vissza egy objektumot, szükség van: az első, hogy állapítsa meg a függvény úgy, hogy annak jelentősége volt a visszatérési típus osztály, másrészt, hogy visszatérjen a tárgy segítségével rendszeresen szereplő visszatérés. Azonban, ha a tárgy iránt tartalmaz destruktor, ebben az esetben, vannak hasonló problémák a „váratlan” a pusztítás a tárgyat.
osztály ClassName nyilvános:
ClassName ()
cout <<'Работа конструктора \n';
>
ClassName ()
cout <<'Работа деструктора \n';
>
>;
ClassName F ()
ClassName obj;
cout <<'Работа функции f \n';
visszatérés obj;
>
Ez a program a következő fog történni
tervezési munkák
tervezési munkák
Munka f
munka destructor
munka destructor
munka destructor
konstruktorok másolata
Constructor hívják kétszer C1 és obj. Vannak azonban három destruktorok. Hogy érti ezt? Egyértelmű, hogy egy destruktor elpusztítja c1, egy másik - obj. „Felesleges” destruktor kihívás (második sor) nevezik az úgynevezett ideiglenes objektum. amely egy példányt a visszaadott objektum. Ezt a példányt akkor keletkezik, ha a függvény egy tárgyat. Miután a függvény a értéke végzett ideiglenes objektum destructor. Világos, hogy ha a destruktor például felszabadítja a dinamikusan memóriát, a pusztítás ideiglenes objektum vezet megsemmisítése a visszaadott objektum.
Az egyik módja, hogy kb ez a fajta probléma, hogy hozzon létre egy speciális tervező - konstruktorok másolata. A másolat a kivitelező, valamint másolatát kivitelező lehetővé teszi, hogy pontosan meghatározzák a teremtés rendjében az objektum másolatát.
Bármilyen másolás kivitelező a következő formában:
classname (const classname obj)
. // kivitelező szervezet
>
osztály ClassName
nyilvános:
ClassName ()
cout <<'Работа конструктора \n';
>
ClassName (const ClassName obj)
cout <<'Работа конструктора копирования\n';
>
ClassName ()
cout <<'Работа деструктора \n';
>
>;
main ()
ClassName c1; // konstruktor
ClassName c2 = c1; // hívás copy konstruktor
>
Megjegyzés: A copy konstruktor nem befolyásolja az értékadó operátor.
Most, hogy van egy példánya kivitelező, akkor nyugodtan át tárgyakat paraméterek funkciók és vissza tárgyakat. Ebben az esetben a hívások száma a tervezők fog egyezni a hívások száma a destruktor, és mivel másolatát az oktatás folyamatában mára ellenőrzött, jelentősen csökkenti a valószínűségét váratlan pusztulása az objektumot.
Mutatók és hivatkozások tárgyak
Mostanáig a hozzáférést a tagok a tárgy végezzük a műveletet. „”. Ez helyes, ha dolgozik egy tárggyal. Hozzáférés azonban a tagok a tárgy lehet végezni, és egy mutatót az objektum. Ebben az esetben a művelet általában alkalmazott nyíl „->”.
A mutató egy objektum bejelentett ugyanúgy, mint egy mutató a változó minden formáját.
érvényteleníti ToZero (_3d * VEC)
A C ++, akkor nem ugyanaz a dolog használata nélkül mutatókat hivatkozások segítségével.
void ToZero (_3d VEC)
vec.set (0,0,0); // használ ""
>
Ezzel szemben át, mint a paraméter a tárgy, a referencia paraméter azt sugallja, hogy a funkció, amely továbbított a paramétert kell mozgatni nem másolat a továbbított objektum, nevezetesen azok továbbított objektum.
_3d _3d :: operator = (_3d b)
Használja, mint a visszatérési érték a kapcsolat biztosítja, hogy visszatért eredményeként ez a funkció pontosan a tárgy, amely felhívja a művelet „=”, és nem egy másolatot.