Professional Documents
Culture Documents
PRZYKADOWY ROZDZIA
SPIS TRECI
KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG
C++Builder Borland
Developer Studio 2006.
Kompendium programisty
Autor: Andrzej Daniluk
ISBN: 83-246-0494-4
Format: B5, stron: 744
TWJ KOSZYK
DODAJ DO KOSZYKA
CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK
CZYTELNIA
FRAGMENTY KSIEK ONLINE
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
Wstp ................................................................................................................................................................11
Rozdzia 1.
Rozdzia 2.
pdf\C++Builder
Borland
Developer
Studio
2006.
Kompendium
3
Rozdzia 3.
4 (29-05-06/14:06) D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\_Sp
Spis treci
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\_Spis treci.doc (29-05-06/14:06)
Rozdzia 4.
Rozdzia 5.
Tablice ...........................................................................................................................................................267
Tablice dynamicznie alokowane w pamici ...................................................................267
Tablice dynamiczne ........................................................................................................270
Tablice otwarte ...............................................................................................................274
Tablice struktur ..............................................................................................................276
Tablice wskanikw do struktur ..............................................................................279
Odwoania do elementw tablicy wskanikw do struktur .....................................281
Podsumowanie ...............................................................................................................284
Rozdzia 6.
6 (29-05-06/14:06) D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\_Sp
Spis treci
hash_set ....................................................................................................................293
hash_map .................................................................................................................294
hash_multiset ...........................................................................................................295
hash_multimap .........................................................................................................296
Obiekty funkcyjne ..........................................................................................................297
Adaptery .........................................................................................................................300
Adaptery iteratorw .................................................................................................300
Adaptery kontenerw ...............................................................................................300
Adaptery obiektw funkcyjnych ..............................................................................302
Algorytmy ......................................................................................................................303
Alokatory ........................................................................................................................305
Valarray ..........................................................................................................................306
Podsumowanie ...............................................................................................................308
Rozdzia 7.
Rozdzia 8.
Rozdzia 9.
Rozdzia 10.
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\_Spis treci.doc (29-05-06/14:06)
Rozdzia 11.
Rozdzia 12.
Rozdzia 13.
8 (29-05-06/14:06) D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\_Sp
Spis treci
Rozdzia 15.
Rozdzia 16.
Rozdzia 17.
Rozdzia 18.
Rozdzia 19.
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\_Spis treci.doc (29-05-06/14:06)
10
Dodatek A
GRAPPLE .................................................................................................................................................677
Zbieranie wymaga ........................................................................................................678
Modelowanie urzdzenia .........................................................................................678
Protok ....................................................................................................................678
Interakcje ..................................................................................................................679
Identyfikacja wsppracujcych systemw ..............................................................679
Analiza ...........................................................................................................................680
Przypadki uycia ......................................................................................................680
Zmiany stanu systemu ..............................................................................................681
Wstpny model klas programu kontrolujcego zewntrzny system wbudowany ...682
Projektowanie .................................................................................................................682
Statyczny model klas programu kontrolujcego zewntrzny system wbudowany .....683
Diagram artefaktw .................................................................................................684
Diagramy czynnoci .................................................................................................684
Kodowanie .....................................................................................................................685
Wdroenie ......................................................................................................................690
Graficzny interfejs uytkownika ....................................................................................691
Kodowanie ...............................................................................................................693
Podsumowanie ...............................................................................................................693
Dodatek B
10 (29-05-06/14:06) D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\_S
Na podstawie wiadomoci przedstawionych w poprzednich rozdziaach miao moemy wywnioskowa, i wskanik okrelonego typu nie moe wskazywa na dane odmiennych typw. Niemniej jednak od tej reguy istnieje pewne bardzo wane odstpstwo. Rozpatrzmy sytuacj, w ktrej
zaimplementowalimy w programie pewn klas zwan klas bazow oraz klas z niej dziedziczc czyli klas pochodn (potomn). Okazuje si, e wskaniki do klasy bazowej mog
rwnie w okrelonych sytuacjach wskazywa na reprezentantw lub elementy klasy pochodnej.
Zamy, i w programie zaimplementowalimy klas bazow TStudent z publiczn funkcj
skadow przechowujc nazwisko pewnego studenta. Nastpnie stworzymy klas pochodn
TEgzamin z publiczn funkcj skadow przechowujc ocen, jak otrzymaa dana osoba z egzaminu z wybranego przedmiotu. W funkcji main() zadeklarujemy zmienn infoStudent jako
wskanik do klasy TStudent:
TStudent *infoStudent;
druku
pdf\C++Builder
Borland
Developer
Studio
2006.
Kompendium
237
238
Okazuje si, e zmienna deklarowana jako wskanik do typu bazowego TStudent moe wskazywa nie tylko na obiekty klasy bazowej, ale rwnie i pochodnej:
infoStudent=&student;
infoStudent=&egzamin;
Za pomoc tak okrelonego wskanika infoStudent mona uzyska dostp do wszystkich elementw klasy TEgzamin odziedziczonych po klasie TStudent, tak jak pokazano to na listingu 4.1.
Listing 4.1. Kod gwnego moduu Unit_R4_01.cpp projektu Projekt_R4_01.bdsproj wykorzystujcego wskaniki
i odwoania do typw pochodnych
#include <iostream>
#pragma hdrstop
using namespace std;
class TStudent
// klasa bazowa
{
char nazwisko[40];
public:
void __fastcall jakiStudent(char *s)
{strcpy(nazwisko, s);}
void __fastcall pokazN() {cout << nazwisko << endl;}
};
//--------------------------------------------------------class TEgzamin: public TStudent
// klasa pochodna
{
char ocena[5];
public:
void __fastcall egzaminInformatyka(char *e)
{strcpy(ocena, e);}
void __fastcall pokazE() {cout << ocena << endl;}
};
//--------------------------------------------------------int main()
{
// wskanik do klasy TStudent (bazowej)
TStudent *infoStudent;
// student-egzemplarz klasy TStudent
TStudent student;
// wskanik do klasy TEgzamin (pochodnej)
TEgzamin *eInfoStudent;
// egzamin-egzemplarz klasy TEgzamin
TEgzamin egzamin;
// wskanik infoStudent wskazuje na egzemplarz
// klasy TStudent
infoStudent=&student;
238(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
239
infoStudent->jakiStudent("Wacek Jankowski");
// wskanik infoStudent wskazuje na egzemplarz
// klasy Tegzamin, bdcej klas pochodn wzgldem
// klasy bazowej TStudent
infoStudent=&egzamin;
infoStudent->jakiStudent("Janek Wackowski");
// sprawdzenie poprawno ci przypisae
student.pokazN();
egzamin.pokazN();
cout << endl;
// funkcje egzaminInformatyka() i pokazE() s
// elementami klasy pochodnej. Dostp do nich uzyskujemy
// za pomoc wskanika eInfoStudent
eInfoStudent = &egzamin;
eInfoStudent->egzaminInformatyka("Egz. Informatyka 2.5");
infoStudent->pokazN();
eInfoStudent->pokazE();
cout << endl;
// uzyskanie dostpu do funkcji skadowej klasy pochodnej
// za pomoc wskanika do klasy bazowej
((TEgzamin *)infoStudent)->pokazE();
cin.get();
return 0;
}
//---------------------------------------------------------
ledzc powysze zapisy, z atwoci przekonamy si, i wskanik do klasy bazowej moe
rwnie dobrze wskazywa na te elementy klasy pochodnej, ktre s zdefiniowane rwnie w klasie bazowej, z tego wzgldu, e klasa TEgzamin dziedziczy publiczne elementy klasy TStudent.
Jednak, uywajc w prosty sposb wskanika do klasy bazowej, nie mona uzyska dostpu
do tych elementw, ktre wystpuj jedynie w klasie pochodnej. W przypadku, gdy zadalibymy uzyskania dostpu np. do funkcji skadowej pokazE() klasy pochodnej, naleaoby wykorzysta zmienn studentInfo bdc jawnym wskanikiem do klasy TEgzamin. Jeeli mimo
wszystko kto zdecydowaby si, aby za pomoc wskanika do klasy bazowej uzyska dostp
do jakiego elementu klasy pochodnej, bdzie musia wykona w odpowiedni sposb operacj
rzutowania typw:
((TEgzamin *)infoStudent)->pokazE();
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
239
240
Funkcj wirtualn (ang. virtual function) nazywamy tak funkcj, ktra jest zadeklarowana
w klasie bazowej za pomoc sowa kluczowego virtual, a nastpnie w takiej samej postaci
definiowana rwnie w klasach pochodnych. Funkcje takie bardzo czsto okrela si mianem
funkcji kategorii virtual. Ponownie definiujc funkcj wirtualn w klasie pochodnej, moemy (ale
nie musimy) powtrnie umieszcza sowo virtual przed jej nazw. Funkcje wirtualne maj
bardzo ciekaw waciwo. Charakteryzuj si mianowicie tym, i podczas wywoywania dowolnej z nich za pomoc odwoania lub wskanika do klasy bazowej wskazujcego na egzemplarz klasy pochodnej, aktualna wersja wywoywanej funkcji kadorazowo ustalana jest w trakcie
wykonywania programu z rozrnieniem typu wskazywanej klasy. Klasy, w ktrych zdefiniowano
jedn lub wicej funkcji wirtualnych, nazywamy klasami polimorficznymi.
Jako praktyczny sposb wykorzystania klas polimorficznych rozpatrzmy przykad, gdzie zadeklarowano nieskomplikowan klas bazow TBazowa z funkcj pokazB() kategorii virtual,
ktrej jedynym zadaniem jest wywietlenie odpowiedniego tekstu. Poniewa funkcja jest rzeczywicie funkcj wirtualn, moemy j z powodzeniem powtrnie zdefiniowa (tzn. zdefiniowa jej kolejn wersj) w klasie pochodnej Tpochodna, dziedziczcej publiczne elementy klasy
TBazowa. Sytuacj t ilustruje listing 4.2.
Listing 4.2. Kod gwnego moduu Unit_R4_02.cpp projektu Projekt_R4_02.bdsproj jako przykad wykorzystania
klas polimorficznych
#include <iostream>
#pragma hdrstop
using namespace std;
class TBazowa {
public:
__fastcall TBazowa() {pokazB();}
// konstruktor
virtual void __fastcall pokazB()
{cout << "Jestem klasa bazowa" << endl; }
};
//--------------------------------------------------------class TPochodna : public TBazowa {
public:
__fastcall TPochodna() {pokazB();}
// konstruktor
/*virtual*/ void __fastcall pokazB()
{cout << "Jestem klasa pochodna" << endl;}
};
//--------------------------------------------------------int main()
{
TPochodna pochodna;
// wywoanie funkcji pokazB()
cin.get();
return 0;
}
//---------------------------------------------------------
240(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
241
Jak atwo zauway, w celu wywoania funkcji pokazB() w gwnej funkcji main() zawarto
jedynie deklaracj egzemplarza klasy pochodnej. Wynika to z faktu, i zarwno klasa bazowa,
jak i pochodna zawieraj odpowiednio zaimplementowane konstruktory.
Na listingu 4.3 zamieszczono przykad ilustrujcy ide posugiwania si wskanikami do klas
polimorficznych, co w efekcie pozwala na pominicie jawnych deklaracji konstruktorw odpowiednich klas.
Listing 4.3. Kod gwnego moduu Unit_R4_03.cpp projektu Projekt_R4_03.bdsproj wykorzystujcego wskaniki
do klas polimorficznych
#include <iostream>
#pragma hdrstop
using namespace std;
class TBazowa {
public:
virtual void __fastcall pokazB()
{cout << "Jestem klasa bazowa" << endl; }
};
//--------------------------------------------------------class TPochodna : public TBazowa {
public:
/*virtual*/ void __fastcall pokazB()
{cout << "Jestem klasa pochodna" << endl;}
};
//--------------------------------------------------------int main()
{
TBazowa bazowa;
TBazowa *ptrBazowa;
TPochodna pochodna;
ptrBazowa = &bazowa;
ptrBazowa->pokazB();
// wywoanie funkcji pokazB() klasy TBazowa
ptrBazowa=&pochodna;
ptrBazowa->pokazB();
// wywoanie funkcji pokazB() klasy TPochodna
cin.get();
return 0;
}
//---------------------------------------------------------
W podanym przykadzie w klasie bazowej definiowana jest funkcja wirtualna pokazB(), po czym
jej kolejna wersja zdefiniowana jest wzgldem klasy pochodnej. W gwnej funkcji main()
zawarto w kolejnoci deklaracj egzemplarza bazowa klasy bazowej, wskanika ptrBazowa do
klasy bazowej i egzemplarza pochodna klasy pochodnej. Dziki instrukcjom:
ptrBazowa = &bazowa;
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
241
242
W analogiczny sposb mona dokona wywoania funkcji pokazB() klasy pochodnej, posugujc
si adresem egzemplarza klasy pochodnej. Poniewa funkcja pokazB() jest w swoich klasach
funkcj wirtualn, zatem w trakcie dziaania programu decyzja o tym, ktra wersja tej funkcji
jest aktualnie wywoywana, zapada na podstawie okrelenia typu egzemplarza klasy aktualnie
wskazywanego przez wskanik ptrBazowa.
Podczas pracy z funkcjami wirtualnymi moliwe jest rwnie wykorzystywanie parametru jako
odwoania do klasy bazowej. Odpowiednio konstruowane odwoania do klasy bazowej umoliwiaj wywoanie funkcji wirtualnej z jednoczesnym przekazaniem jej argumentu. Przedstawiony na listingu 4.4 program jest modyfikacj algorytmu z poprzedniego wiczenia. Zadeklarowano w nim klas bazow, dwie klasy pochodne oraz funkcj przeadowan, zawierajc
poprzez parametr formalny x odwoanie do klasy bazowej:
//--------------------------------------------------------void __fastcall pokazB(TBazowa &x)
// odwoanie do klasy bazowej
{
x.pokazB();
return;
}
//---------------------------------------------------------
Dziki tak skonstruowanemu odwoaniu aktualna wersji funkcji pokazB(), ktra powinna by
w danym momencie dziaania programu wywoana, ustalana jest w gwnej funkcji main() na
podstawie typu, do ktrego odwouje si jej parametr aktualny.
Listing 4.4. Kod gwnego moduu Unit_R4_04.cpp projektu Projekt_R4_04.bdsproj wykorzystujcego odwoanie
do klasy polimorficznej
#include <iostream>
#pragma hdrstop
using namespace std;
class TBazowa {
public:
virtual void __fastcall pokazB()
{cout << "Jestem klasa bazowa" << endl; }
};
//--------------------------------------------------------class TPochodna1 : public TBazowa {
public:
/*virtual*/ void __fastcall pokazB()
{cout << "Jestem 1 klasa pochodna" << endl;}
};
//--------------------------------------------------------class TPochodna2 : public TBazowa {
public:
/*virtual*/ void __fastcall pokazB()
{cout << "Jestem 2 klasa pochodna" << endl;}
};
//---------------------------------------------------------
242(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
243
Wskazwka
Bardzo czsto funkcje zawierajce odwoania do klas polimorficznych maj
(chocia niekoniecznie) takie same nazwy, jak funkcje wirtualne wzgldem danej
klasy. Chocia funkcje te mog mie takie same nazwy, nie naley utosamia ich
z funkcjami przeadowanymi. Pomidzy konstrukcj funkcji przeadowywanych
i ponownym definiowaniem funkcji wirtualnych istniej powane rnice, np. prototypy
funkcji wirtualnych musz by identyczne, funkcje przeadowane za maj rn liczb
lub typ parametrw. Z tego powodu ponowne definiowanie funkcji wirtualnych nazywa
si przykrywaniem lub nadpisywaniem funkcji.
Tematem poprzedniego podrozdziau byy funkcje wirtualne, czyli funkcje deklarowane ze sowem kluczowym virtual. Z przedstawionych przykadw atwo wywnioskujemy, i wielk
ich zalet jest to, e s one odpowiednio przykrywane w klasach pochodnych. Jednak w jzyku C++ sowo virtual posiada jeszcze jedno znaczenie, suy mianowicie do deklarowania
tzw. wirtualnych klas bazowych.
Rozpatrzmy sytuacj, w ktrej potrzebujemy zdefiniowa w programie pewn klas bazow
TBazowa, dwie klasy pochodne TPochodna1 i TPochodna2 dziedziczce po klasie bazowej i dodatkowo trzeci klas pochodn TPochodna3, dziedziczc elementy publiczne klas TPochodna1
i TPochodna2. W kadej z klas zdefiniujmy po jednej funkcji zwracajcej pewn warto cakowit. Przyjte zaoenia ilustruje rysunek 4.1 oraz listing 4.5.
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
243
244
Rysunek 4.1. Idea poziomego dziedziczenia klas. Klasa TPochodna3 dziedziczy poziomo (wielokrotnie)
po klasach TPochodna1 i TPochodna2
Listing 4.5. Kod gwnego moduu Unit_R4_05.cpp projektu Projekt_R4_05.bdsproj wykorzystujcego
standardowe klasy bazowe
// Program nie zostanie skompilowany !
#include <iostream>
#include <vcl>
#pragma hdrstop
using namespace std;
class TBazowa {
public:
int i;
int __fastcall pokazB()
{cout << "Jestem klasa bazowa" << endl;
return i; }
};
//--------------------------------------------------------class TPochodna1 : public TBazowa {
public:
int j;
int __fastcall pokazP1()
{cout << "Jestem 1 klasa pochodna" << endl;
return j;}
};
//---------------------------------------------------------
244(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
245
Podczas prby uruchomienia powyszego programu spotka nas przykra niespodzianka polegajca na tym, e program si po prostu nie skompiluje! Wynika to z faktu, i jego konstrukcja jest niejednoznaczna, poniewa wywoanie:
klasa.i = 100;
z tego powodu, e kady egzemplarz klasy TPochodna3 zawiera dwie kopie elementw skadowych klasy TBazowa. Poniewa w tej sytuacji istniej dwie kopie zmiennej i (deklarowanej
w klasie bazowej), kompilator nie ma najmniejszej wiedzy na temat, ktr kopi zmiennej ma
wykorzysta t odziedziczon przez klas TPochodna1 czy t z klasy TPochodna2.
Jeeli dwie lub wiksza liczba klas dziedziczy z tej samej klasy bazowej, moemy zapobiec
sytuacji, w ktrej kopia klasy bazowej jest powielana w klasach potomnych w sposb niekontrolowany. Istnieje kilka sposobw, aby przeciwdziaa takiemu samopowielaniu si klasy
bazowej. Najprostszym rozwizaniem jest zadeklarowanie klas pochodnych jako klas kategorii virtual, tak jak pokazano to na listingu 4.6.
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
245
246
246(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
247
}
//---------------------------------------------------------
Wskazwka
Klasy wirtualne naley wykorzystywa tylko wtedy, gdy w programie istnieje
konieczno wielokrotnego dziedziczenia klas. Gdy klasa bazowa dziedziczona
jest jako wirtualna, w programie tworzona jest tylko jedna jej kopia. Przez pojcie
wielokrotnego dziedziczenia (dziedziczenia poziomego) rozumiemy sytuacj,
w ktrej jedna klasa jednoczenie dziedziczy po wikszej liczbie klas.
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
247
248
<vcl>
<sysutils.hpp>
<iostream>
polimorficzne w stylu VC/
248(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
249
ptrP2->dane(5,5);
ptrP2->pokazPole();
// wywoanie destruktorw klas
delete ptrB;
delete ptrP1;
delete ptrP2;
cout << endl;
system("P [SE");
return 0;
}
//---------------------------------------------------------
Analizujc powyszy program, natychmiast zauwaymy, i zainicjowanie kolejnych egzemplarzy klas wymaga utworzenia odpowiednich wskanikw oraz wykorzystania operatora new alokujcego je na stercie. Ze wzgldu na to, e typowi bazowemu oraz poszczeglnym typom
pochodnym zosta dynamicznie przydzielony pewien obszar pamici, ma sens mwienie o utworzeniu obiektw poszczeglnych klas, zwaszcza e interfejs (sposb wywoania elementw):
ptrP1->dane(2,2);
ptrP1->pokazPole();
ptrP2->dane(5,5);
ptrP2->pokazPole();
obu klas pochodnych jest taki sam pomimo pewnych rnic w wykonywanych przez nie obliczeniach.
Wskazwka
W dalszej czci ksiki pojcia obiekt bdziemy uywa w odniesieniu do elementw
programistycznych, do ktrych w trakcie dziaania programu zawsze mona wysa
komunikaty oznaczone stereotypami <<create>> i <<destroy>>, to znaczy wielokrotnie
wywoa ich konstruktor i destruktor. Oznacza to, i czasem ycia obiektw stworzonych
na bazie odpowiednich klas mona niemal dowolnie zarzdza.
Posugujc si funkcjami wirtualnymi w C++, naley zwrci baczn uwag na sposb inicjowania elementw klas. Dane takich typw, jak odwoania oraz zmienne, musz by zawsze we
waciwy sposb inicjowane. Jednak niezalenie od tego, w jaki sposb s inicjowane, bd dalej
pozostawa niezdefiniowane przed wywoywaniem konstruktora klasy bazowej. W C++Builderze
odpowiednie elementy biblioteki klas pisanych na wzr VCL s zawsze inicjowane wartoci
zero w momencie wywoywania ich konstruktorw (listing 4.8).
Listing 4.8. Kod gwnego moduu Unit_R4_08.cpp projektu Projekt_R4_08.bdsproj
#include <vcl>
#include <sysutils.hpp>
#pragma hdrstop
class TBazowa : public TObject
{
public:
__fastcall TBazowa() {init();}
virtual void __fastcall init() { }
};
//---------------------------------------------------------
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
249
250
W podanym przykadzie wyjtek przechwytywany jest ostatecznie przez konstruktor klasy bazowej, tak jak pokazano to sekwencj rysunkw 4.2 4.5.
250(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
251
Klas, ktra zawiera przynajmniej jeden element w postaci tzw. funkcji czysto wirtualnej (ang.
pure virtual function), nazywamy klas abstrakcyjn (ang. abstract class). W oglnej postaci
funkcj czysto wirtualn moemy zapisa nastpujco:
virtual typ __fastcall nazwa_funkcji(<lista_parametrw>) = 0;
Funkcje takie s zawsze deklarowane w klasie bazowej, jednak nigdy nie s definiowane wzgldem niej. Funkcja czysto wirtualna poczona z klas abstrakcyjn oznacza, e funkcja taka
nie ma swojej implementacji w macierzystej klasie. Funkcja czysto wirtualna zawsze powinna
zosta zaimplementowana w klasach pochodnych.
Jako przykad praktycznego wykorzystania klasy abstrakcyjnej rozpatrzmy sytuacj, w ktrej
klasa bazowa zawiera deklaracj funkcji pokazPole(), traktowanej jako funkcja czysto wirtualna.
Listing 4.9. Modu Unit_R4_09.cpp projektu Projekt_R4_09.bdsproj wykorzystujcego klas abstrakcyjn w stylu
biblioteki klas VCL
#include <vcl>
#include <sysutils.hpp>
#include <iostream>
using namespace std;
class TBazowa : public TObject
{
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
251
252
}
//---------------------------------------------------------
Na rysunku 4.6 przedstawiono statyczny diagram klas dla przykad z listingu 4.9.
252(29-05-06/14:07)
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium programisty\
253
nie pozostawia nam cienia wtpliwoci, gdy nie mona skonstruowa obiektu na podstawie
klasy zawierajcej funkcj czysto wirtualn.
Wskazwka
Nie mona tworzy obiektw na bazie klas abstrakcyjnych. Klas takich uywamy
wycznie w charakterze klas bazowych dziedziczonych przez inne klasy pochodne.
Moliwe jest jednak tworzenie wskanikw nietraktowanych jako dynamiczne obiekty
w stylu jzyka C++ (tzw. wskanikw tradycyjnych) do tego typu klas, np.:
TBazowa *ptrB;
D:\Roboczy Jarek\makiety poprawki i druku pdf\C++Builder Borland Developer Studio 2006. Kompendium
programisty\04.doc (29-05-06/14:07)
253