C osztály, propascal - minden a programozók

C ++ osztályok

Mi cpp

Az összes nyelv, amely támogatja a módszer az objektum-orientált programozás, C ++, talán ez biztosítja a legnagyobb lehetőséget és a rugalmasan kezelheti létrehozása objektumok, osztályok, hozzáférést a tagok az osztályok, a memória kezelése, kiosztja tárgyakat. Azonban semmi szabad nem történik meg, és a teljesítmény és a rugalmasság, a C ++ nyelven is meg kell fizetni, és nem nyilvánvaló összetettsége számos terveit.

Szintaxis leírása az osztály

BazovyeKlassy egy névsort a bázis osztályok jelzi az előírást hozzáférést az alapvető osztályok. Ha az osztályban nincs alaposztályokat, ez a lista nem lehet írni (és nem hozott előjátéka a colon).

És-osztály tagjai az osztály definíció csak be, de később ismertetjük. Például:

Fontos! A bejelentett (de még nem meghatározott) osztályok csak akkor lehet használni, ha nincs szükség tudni, hogy a memória mennyisége által kiosztott osztály objektum - azaz a használata engedélyezett, de nem a nevek egyes osztályok csak akkor engedélyezett mutatók és referenciák leírásai:

(A jövőt: a probléma csak úgy tűnik erőltetett az GroupX osztály (implicit) által meghatározott tervező, aki létre kell hoznia az Besorolás tárgyak, semmit róluk, anélkül, hogy tudnának róla.).

Ez a probléma nem fordul elő más programozási nyelvek (például Delphi, Java, C #), amelyben a hozzáférést az osztály objektum megy csak chereh mutatók. Azonban a C ++ osztály objektum úgy, mint egy adat (bitsorozat), nem pedig mint egy mutatót az adatokat.

Való hozzáférés joga módszerek és mezők az osztály

A C ++, három szintje van a hozzáférési jogok a tagjai az osztály.

Az osztály tagjai bejelentették az állami szakaszok, bárhonnan elérhető a programban.

Tagjai az osztály deklarált szakaszok védett, ahová csak az osztály maga (és módszerek), valamint a származékos osztályok tőle.

Fields és módszerek nyilvánították magán, csak akkor állnak rendelkezésre egy osztályon belül (és módszerek), valamint a „barátságos” osztályok. Ez a szint a hozzáférés is alkalmazni kell, az osztály tagjai, amelyekhez hozzáférési jogok nem kifejezetten megadva.

Gyakran van olyan helyzet, amikor több különböző osztályok szorosan kapcsolódnak egymáshoz. Például, ha az osztály-könyvtár létrehozása dolgozni vektor algebra, beleértve a Mátrix és vektor osztályok, ez nem megvalósítható nehéz szétválasztani ezeket osztályokba, nagyon tartós, amelyhez kapcsolódnak. És ha így a Mátrix osztály csak a hozzáférést nyilvános tagjai az osztály vektor, a műveletet a mátrixok és vektorok nehéz lesz végrehajtani a szükséges hatékonyságot. Ha nyilvánosságra belső reprezentáció a vektor, akkor elveszíti ezt a fontos minőségi objektum-orientált modell beágyazásként végrehajtásának részleteit egy osztályban.

Ahhoz, hogy hozzáférjen a belső ábrázolása az osztály csak bizonyos más osztályokba, így akadályozva meg az ilyen hozzáférés végig, a „barátságos osztály” vezették be a C ++. Osztály, a felhasználó-barát, hozzáfér valamennyi tagja, beleértve nyilvánították magán.

A kivitelező inicializálni tárgyak ennek az osztálynak (azaz inicializálás, és nem a teremtés az objektum lehet elhelyezni nem csak a dinamikusan memóriát, hanem a verem (lokális változóként a funkció).

Jellemző, hogy a C ++ konstruktőrök nevezzük, ha az objektum nem jön létre, amíg a végén. Ezért vannak korlátai a fellebbezést a tervező, hogy a többi osztály módszerek (különösen a virtuális módszerek).

Syntax leírások tervező

A kivitelező C ++ ugyanaz a neve, mint a neve az osztály, és lehet paramétereket (vagy nem őket):

Két konstruktőrök ismertet: az egyik paraméter nélkül (és ez lesz az alapértelmezett konstruktor), a másik - egyetlen paraméter string típusú.

És most új objektumok létrehozásához:
C x; // az alapértelmezett konstruktor neve
// jelenik // n = 0 C y =
«Abc»; // konstruktor hívják meg-paraméter
// jelenik // n = 3 C z ( «abc»); // az előző esetben
// jelenik // n = 3 C * p =
új C (); // objektum jön létre a dinamikus memória kiosztás
// jelenik // n = 0 C * p =
új C ( «abcd»); // másik dinamikusan generált
objektum
// jelenik // n = 4

Azaz, a kivitelező neve:
• ha kifejezetten létre egy objektumot egy dinamikusan allokált memóriát használó üzemeltető új;
• Ha inicializálja a leírt változók és az osztály tagjai;
• Ha másolatot tárgyak (de erről bővebben később).

Egy fontos típusa a kivitelező az úgynevezett „copy konstruktor”. A másolat kivitelező minősül konstruktor egyetlen paramétert (vagy az első lehetőség, ha más paraméterek alapértelmezett értékek):
• const utalás az objektum az osztály;
• hivatkozás az objektum az osztály;
• instabil (illékony) vagy konstans referencia instabil utalás az objektum az osztály.

A másolat kivitelező neve:
• Az inicializálás létrehozott objektum egy másik objektumot az azonos osztályba tartoznak;
• az átadás a paraméter (nem mutató!) A funkció;
• Ha visszatér az értéket (nem a mutató!) Függvény;
• Ha másolás megbízást tárgyat (de csak ha az osztály nem felülírják az üzemeltető hozzárendelés!).

A másolat kivitelező és hozzárendelés

Lehetőség C ++ meghatározni, mint egy másolatot a kivitelező, valamint értékadó operátor, hogy felülbírálja az osztály igényel különösen gondos használatával kapcsolatban az értékadó operátor az ilyen esetekben, mert meg kell tudni, hogy pontosan mi lesz az úgynevezett: a másolatot a kivitelező, valamint az értékadó operátor. Például:

>;
És most mindez használata:
A a1; // úgynevezett A () inicializálni a kivitelező
egy
Egy a2 (a1);
// copy konstruktor neve
A a3 = a2;
// copy konstruktor hívódik újra
B b;
A4 (b);
// kivitelező nevezzük (const B), // mivel a változó
// objektum inicializálunk B osztályú
A a5 = b;
// kivitelező nevezzük (const B)
a1 = a5;
// úgynevezett újraírásra értékadó operátor
a2 = b;
// Nos, itt - a teljes ünnep:
// - az objektum b létrehoz egy ideiglenes objektum osztályú
// Konstruktorban A (const B)
// - újraírásra segítségével az értékadó operátor,
// a logikai változó a2 létrehozott átmeneti eszköz

Destruktor bejelentett C ++ az alábbiak szerint:

ClassName ();
Ennek célja -, hogy készítsen a tárgy eltávolítására. Például, a kibocsátás a foglyul ejtett tárgy források.

A destruktor neve előtt a kiadás az emlékezet számára kijelölt objektum:
• ha kifejezetten nem törli egy objektum elhelyezett, a kupac, a delete operátor;
• a kilépés a változó, amelynek értéke az objektum (objektum nevét, nem egy mutatót egy objektum!) Szabályozatlan.

Destructor lehet nyilvánítani a virtuális és felülírt egy származtatott osztály.

Ez a kulcsszó

Az erre a kulcsszóra hozzáférést biztosít a módszerek az osztály egy mutatót az osztály objektum is. ez:
• Név index (függetlenül attól, hogy az objektum létrehozásának);
• const mutató, azaz osztály módszerek nem tudja megváltoztatni az értékét.

Nyomós new és delete operátorok

Az új üzemeltető létrehozásához használt objektumok dinamikusan memóriát, és az üzemeltető törli eltávolítására használják az előzőleg létrehozott dinamikusan memóriát tárgyakat. C ++ lehetővé teszi a programozó, hogy felülírják ezeket a szolgáltatók, és ezáltal egy olyan memória kezelési mechanizmus.

Felülbírálja az új kezelő legyen az első típusú paramétert size_t (használt típusú C ++, hogy meghatározza a méret a memória, és valójában egész szám), és visszatér a void * (vagyis egy típustalan pointer) egy mutató a lefoglalt memória az objektum .

Felülbírálat törölni üzemben tartónak típusú paramétert void *, jelezve a memória által elfoglalt kivehető objektumot.

És az üzemeltető új, üzemeltető és törölje a statikus módszer, és ezért nem képesek hozzáférni az adatokhoz létrehozott vagy törölt objektum. (Azonban, mivel a void * mutatóban lehet alakítani egy mutatót a objektumot, a programozó kaphat az adatokat a tárgy, de nem erre -. Vannak konstruktőr és destruktorai adatkezelés létrehozni és törölni).

Az öröklődés lehetővé teszi, hogy meghatározza a származtatott osztály, mint egy kiterjesztése az alap osztály. Továbbá, minden tagja az alap osztály létezik a származtatott osztály. De nem mindegyik áll rendelkezésre a munka hozzáférési szabályokat.

Ismét, ellentétben más objektum-orientált nyelvek (Java, Delphi, C #), C ++ nem közös az összes osztály az alap osztály. Minden osztály, ami nincs meghatározva alaposztályok egyik (esetleg sok) csúcsai osztály hierarchiát.

C ++ - egyike azon kevés nyelvek, amelyek lehetővé teszik a többszörös öröklést, vagyis az osztály lehet több bázis osztályok. Ebben a leszármazott osztály megkapja az összes tagjainak szülőosztály. Nagyon egyszerűsített leírása az osztály
struct D: B1, B2
int n;
>

Meg lehet tekinteni, mint
struct D
B1 __b1;
B2 __b2;
int n;
>
Ebben az esetben lépjünk be a B1 és B2 tagok nem kell emellett meghatározza „mezőnevek» __b1, __b2, és hozzáférhetnek a nevét közvetlenül az objektum osztály D. azonban (mint általában a C ++), vannak árnyalatok, amelyek a későbbiekben még kitérünk .

Ez egy nagyon hatékony eszköz, hogy sok esetben ez természetes, hogy leírja az adatok szerkezetét anélkül, hogy további fogalmakat (például Java «interfészek», Delphi vagy C #). De (mint más C ++ erős minták) ezekre a gazdag lehetőségeit fizetni megnövekedett összetettsége. Például:

A C ++, vannak (és meglehetősen bonyolult) szabályok lehetővé teszik a legtöbb ilyen ütközések. De sok esetben jobb, ha külön megadnunk, mi forog kockán, using namespace prefix:

Többszörös öröklés, és ez a

Vigyázat! Lehetősége miatt többszörös öröklés, ez a mutató értéke a származtatott osztály objektum eltérhet ez a mutató értéke az objektum a szülő osztály (különösen, ha az alap osztály nem volt az első az alap osztály részt)!

Elvont osztályok és tiszta virtuális függvények

Az osztály, hogy tartalmaz legalább egy tisztán virtuális függvény az úgynevezett „absztrakt osztály.” absztrakt osztály objektumok nem hozhatók létre (ideértve az absztrakt osztály nem lehet leírni a változók, bár az is lehetséges, hogy leírja egy mutatót az absztrakt osztály tárgyak - értéküket lehet mutatókat osztályok leszármazott objektumokat.

Egyszerű és virtuális örökség

Tegyük fel, hogy van egy ilyen osztály hierarchiát:
osztály
nyilvános:
int n;
void f ();
>
B1: nyilvános A
>
osztály B2: nyilvános A
>
és C osztályú, hogy származik, és a B1, és a B2.

Az osztály C egy gyermek osztályú és az osztály B1 keresztül-kasul B2 osztályú. Következésképpen, és tartalmaz egy mezőt n, és az f () módszer. Ebben az esetben, van egy kétértelműség: merre (via a B1 vagy B2) van egy hivatkozás a mező N, és az eljárás F () a C osztályú? És általában, milyen sok területen n egy C típusú tárgy? Csak egy? Vagy az egyik mezőt B1 :: n és még egy a B2 :: n? És ha és F módszer () felülbírálja az egyik osztály B1 vagy B2 (és még mindkét kategóriában)? Egyértelmű jelzése az osztály nevét, amikor hivatkozva a módszer nem oldja meg a problémát.

Ezért a C ++ ben bevezette azt a lehetőséget a virtuális öröklés: az osztály nyilatkozatot adni, hogy örökli az alap osztály virtuális, akkor örökölt mezők és módszereket kell osztani a többi virtuális alap osztály örökösök. Ellenkező esetben minden osztálynak saját sorozata örökölt mezők és módszerek. Például:
osztály
nyilvános:
int n;
void f ();
>
B1: virtuális nyilvánosság
>
osztály B2: virtuális nyilvánosság
>
C osztály: nyilvános B1, nyilvános B2
>

Ebben az esetben a B1 és B2 osztály, öröklés tőlük a C-osztály, a tagok közös osztály, mint az öröklést, amely egy megadott virtuális.

És ha nem volt virtuális kulcsszó:
osztály
nyilvános:
int n;
void f ();
>
B1: nyilvános A
>
osztály B2: nyilvános A
>
C osztály: nyilvános B1, nyilvános B2
>

C-osztály tagjai az osztály A «szorozva» a (külön öröklési keresztül B1 és külön-külön öröklési keresztül B2). Minden egyes „copy” lehet elérni nevének megadásával az alap osztály, amely révén a tag már örökölte. Például,
C * x = új C ();
x-> B1 :: f ();