Professional Documents
Culture Documents
Prefa
Sistemul Borland C++ Builder (BCB) este unul dintre cele mai
moderne i mai rspndite sisteme de programare vizual. El conine
instrumente eficiente de elaborare a aplicaiilor de tip Windows, client-server
etc. Avnd drept limbaj de programare C++ (derivat din limbajul C), este n
acelai timp unul dintre cele mai potrivite pachete pentru nvarea programrii
orientate spre obiecte i a celei vizuale.
Prezenta lucrare este un ghid de iniiere n programarea vizual i
programarea orientat spre obiecte cu ajutorul sistemului BCB. Este structurat
n trei capitole, care ofer informaii de baz i exemple demonstrative, menite
s ilustreze aspectele teoretice.
n capitolul I (denumit Platforma BCB) snt descrise modalitile de
utilizare a componentelor specifice majoritii aplicaiilor tip Windows,
precum i algoritmii de elaborare a astfel de aplicaii (inclusiv a celor de
prelucrare a informaiei grafice).
Crearea i gestionarea bazelor de date este una dintre cele mai prioritare
domenii ale programrii. Sistemul Borland C++ Builder conine un set de
utilitare, care permit crearea i/sau ntreinerea bazelor de date, inclusiv de tip
FoxPro, MySQL, Access, Oracle, etc. Algoritmii de lucru cu bazele de date
snt descrii n capitolul II Prelucrarea bazelor de date.
n capitolul III (denumit Programarea Orientat spre Obiecte cu
C++) snt explicate caracteristicile limbajului C++ i mecanismele POO:
incapsularea, motenirea, suprancrcarea operatorilor, polimorfismul etc.
Contieni de complexitatea POO, am inclus o serie de coduri de program, care
(sperm) vor ajuta la nelegerea acestor mecanisme.
Am presupus c cititorul este iniiat cu un limbaj de programare
(preferabil cu C). Chiar dac nu are o astfel de iniiere, urmnd consecvent i
consecutiv paragrafele ghidului, el va reui s obine cunotine i competene
de elaborare a produselor program de tip Windows.
n variant de manuscris, lucrarea a fost experimentat pe studenii
Universitii de Stat din Tiraspol i ai Colegiului Financiar-Bancar A.
Diordia din Chiinu, care au i solicitat apariia ei.
Ea va fi util nu doar studenilor specialitilor de Informatic, dar i
tuturor celorlali interesai de programarea modern.
Autorii
-3-
Capitolul I
Platforma BCB
1. Mediul de dezvoltare integrat BCB
Mediul de dezvoltare BCB include urmtoarele elemente:
Bara de titlu
Bara de instrumente
Paleta cu componente
Fereastra formei
Bara cu instrumente
Object TreeView
Object Inspector
Dup lansarea la execuie a sistemului BCB apar urmtoarele ferestre:
-4-
1. Bara de titlu
Bara de titlu afieaz numele proiectului curent (Project1) i numele
programului (C++ Builder 6).
-5-
-6-
-7-
-8-
3. Bara de instrumente
Bara de instrumente conine butoane cu rol de acces la unele comenzi
(pot fi accesate prin sistemul de meniuri), care ofer posibilitatea de a aduga
sau a exclude instrumente.
4. Paleta de componente
Paleta de componente este format din cteva pagini de componente.
Aceste componente (care mai snt numite i controale) urmeaz a fi plasate pe
suprafaa formei pentru a fi prelucrate. Cele mai utilizate pagini de componente
snt:
Standart conine controalele cel mai des utilizate;
DataAcces conine controale pentru stabilirea legturilor ntre componente;
DataControls conine controale pentru prelucrarea bazelor de date (de ex.
pentru afiarea informaiei dintr-un tabel);
BDE conine controale ce permit stabilirea unei conexiuni cu baza de date,
prin intermediul tabelelor, interogrilor, etc;
ADO asigur accesul aplicaiilor client la date.
5. Fereastra formei
Fereastra formei afieaz o forma curent, pe suprafaa creia se pot
depune controale n perioada de elaborare a proiectului.
-9-
- 10 -
- 11 -
- 12 -
- 13 -
Funcia
__fastcall
TForm1::TForm1(TComponent*
Owner):
TForm(Owner)
- 14 -
3. Aplicaii de consol
Sistemul BCB ofer posibilitatea elaborrii aplicaiilor de consol.
Pentru a crea o astfel de aplicaie:
1) Executm File\New\Other. Apare fereastra New Items:
- 15 -
Exemplu rezolvat
S elaborm o aplicaie de consol care va citi de la tastatur dou
numere ntregi, apoi va afia la consol suma acestor numere.
Realizare:
1) Executm File\New\Other.
2) Efectum un double-click pe pictograma Console Wizard.
3) n fereastra aprut (Console Wizard) selectm limbajul de programare (C
sau C++) i executm Ok.
4) n fereastra editorului de cod (Unit1.cpp) scriem programul:
- 16 -
- 17 -
4. Generaliti
Structura unei clase C++ Builder nu se deosebete esenial de structura
unei clase C++.
n C++ Builder apare un nou modificator de acces: __published. La
acest nivel de protecie snt declarate prototipurile controalelor i
evenimentelor.
Tipul __fastcall este creat n special pentru prelucrarea evenimentelor.
n general sistemul BCB opereaz cu pointeri, din aceast cauz
proprietile i metodele unui obiect snt apelate prin intermediul operatorului
sgeat: ->. n cazul n care acestea nu snt de tip pointer, ele snt apelate prin
intermediul operatorului punct: . (pentru detalii vezi capitolul III).
Dup elaborarea unei aplicaii este creat fiierul final (Project1.exe).
Pentru ca aplicaia BCB s se lanseze la execuie fr erori pe o staie care nu
are instalat sistemul BCB la salvarea proiectului final se vor efectua
urmtoarele modificri:
1) Din meniul Project deschidem ferastra Options.
2) Alegem paleta Packages i scoatem bifa casetei de validare Build
with runtime Packages.
- 18 -
- 19 -
5. Clasa TForm
O aplicaie Windows este format din ferestre, dintre care una este
considerat fereastr principal (implicit prima fereastr este principal). n
C++ Builder ferestrele snt descrise n clasa TForm, din care cauz ele mai snt
numite forme (sau machete).
Pa bara de titlu a formei se afl titlul ei, butoanele de minimizare, de
maximizare, de nchidere i meniul principal (dac acesta exist).
Pe suprafaa zonei client a formei programatorul poate plasa
componente. Pentru a prelucra o form trebuie s cunoatem proprietile,
metodele i evenimentele clasei TForm. Menionm c multe dintre aceste
proprieti i evenimente exist i pentru clasele corespunztoare altor
componente.
- 20 -
ntrebare);
BorderStyle specific stilul chenarului formei. Valorile posibile:
- bsDialog (forma nu poate fi redimensionat, chenarul ei fiind
standard);
- bsSingle (forma nu poate fi redimensionat, marginile chenarului snt
linii);
- bsNone (forma nu poate fi redimensionat, nu are chenar);
- bsSizeable (forma poate fi redimensionat);
- bsToolWindow (la fel ca bsSingle, doar cu un titlu mai mic);
- bsSizeToolWin (la fel ca bsSizeable, doar cu un titlu mai mic).
BorderWitdh indic distana n pixeli dintre zona client i marginile formei.
Caption specific titlul ferestrei (textul care apare pe bara de titlu).
Color stabilete culoarea formei.
Constrains este o proprietate compus format din subproprietile
MaxWidth, MaxHeight, MinWidth, MinHeight. Indic restricii asupra
dimensiunilor formei. Dac toate cele 4 proprieti au valoarea 0, atunci
restricii nu snt.
Cursor specific forma mouse-lui.
Font este o proprietate compus pentru stabilirea mrimii, fontului,
efectelor de stil pentru textele de pe form i a textelor aferente componentelor
de pe form.
FormStyle stabilete stilul formei. Valori posibile:
- fsNormal (form obinuit);
- fsMDIChild (form de tip MDI copil);
- fsMDIForm (form de tip MDI printe);
- fsStayOnTop (form afiat pe Desktop, deasupra celorlalte forme).
Heitch specific nlimea n pixeli a formei.
Hint specific textul care va aprea la plasarea cursorului de mouse pe
form. Acest text apare numai n cazul n care proprietatea ShowHint are
valoarea true.
ModalResult este utilizat pentru o form modal. Aplicaia principal nu
reacioneaz la evenimente att timp ct este deschis o fereastr modal. Prin
aceast proprietate se poate gestiona modul n care a fost nchis fereastra
modal. Din aceast cauz ea nu apare n lista de proprieti din fereastra
Object Inspector.
Name stabilete numele formei (utilizat pe post de identificator al formei).
Position specific dimensiunile i poziia pe care o va avea o form pe
ecran. Valorile posibile:
- poDesigned (forma apare pe ecran n aceeai poziie i aceleai
dimensiuni ca i cele setate la proiectarea ei);
- poDefault (sistemul Windows alege poziia i dimensiunea formei);
- 21 -
- 22 -
OnDockDrop apare cnd un obiect este depus pe form prin operaia dragand-dock.
void __fastcall TForm1::FormDockDrop(TObject *Sender,
TDragDockObject *Source, int X, int Y)
OnDockOver apare cnd un obiect este tras peste form pentru o operaie
drag-and-dock.
void __fastcall TForm1::FormDockOver(TObject *Sender,
TDragDockObject *Source, int X, int Y, TDragState State,
bool &Accept)
OnDragOver apare cnd un obiect este tras peste form pentru o operaie
drag-and-drop.
void __fastcall TForm1::FormDragOver(TObject *Sender,
*Source, int X, int Y, TDragState State, bool &Accept)
TObject
- 23 -
OnHide apare atunci cnd forma este ascuns (de exemplu dac proprietatea
Visible obine valoarea false).
void __fastcall TForm1::FormHide(TObject *Sender)
- 24 -
Exemplu rezolvat
S crem o aplicaie format dintr-o fereastr (fr componente pe ea).
La efectuarea unui click suprafaa formei va deveni de culoare roie, iar al
apsarea tastei h titlul ferestrei se va modifica n Salut! Prima aplicatie BCB.
Realizare:
1) Executm File\New\Application.
2) Prelucrm evenimentul OnClick al formei. Scriem instruciunea:
Form1->Color = clRed;
- 25 -
- 26 -
6. Clasa TButton
Butoanele snt, probabil, cele mai des utilizate controalele n BCB. Ele
snt destinate lansrii la execuie a diferitor aciuni.
7. Clasa TEdit
Un exemplar al clasei TEdit afieaz o caset de editare n care
utilizatorul poate scrie un text sau poate afia un mesaj.
Unele proprieti ale clasei TEdit
AutoSize (de tip logic) permite (pentru valoarea false) sau interzice
redimensionarea automat a casetei (n cazul n care un eveniment ar modifica
- 27 -
Exemplu rezolvat
S crem o aplicaie, a crei fereastr va conine dou casete de editare
(componente de tip TEdit) i dou butoane de comand (Copy i Codific).
Utilizatorul va scrie un text n prima caset, apoi dup efectuarea unui click pe
butonul Copy textul din prima caset va fi copiat n caseta a doua. La
efectuarea unui click pe butonul Codific textul din caseta a doua va fi
codificat.
Realizare:
1) Executm File\New\Application.
2) Plasm componentele conform enunului.
- 28 -
8. Clasa AnsiString
n limbajul C++ nu exist un tip de date ir de caractere, cum ar fi tipul
string n Pascal. Prelucrarea irurilor de caractere n C++ se face prin
intermediul tablourilor de tip char, care snt numite i iruri de caractere.
Mediul C++ Builder motenete toate facilitile oferite de limbajele C i C++
referitoare la lucrul cu iruri de caractere.
- 29 -
- 30 -
9. Clasa TLabel
O component de tip TLabel afieaz o etichet, care se utilizeaz
pentru afiarea textelor. Texul poate poate fi specificat att n perioada de
elaborare a proiectului, ct i n timpul execuiei, prin intermediul proprietii
Caption. Multe dintre proprietile controlului Label coincid cu proprietile
controalelor studiate.
- 31 -
Exemple rezolvate
1. S crem o aplicaie care va calcula aria i perimetrul unui dreptunghi fiind
date dimensiunile dreptunghiului.
Realizare:
1) Executm File\New\Application.
2) Plasm dou componente de tip TEdit (pentru citirea dimensiunilor
dreptunghiului), trei de tip TLabel (pentru denumirile dimensiunilor i pentru
afiarea rezultatelor), un buton de comand.
3) Prelucrm evenimentul OnClick al butonului de comand.
- 32 -
2. Calculatorul
S crem o aplicaie care va efectua operaii aritmetice cu numere reale, a crei
- 33 -
Realizare:
1) Executm File\New\Application.
2) Plasm pe form o caset de editare, 17 butoane de comand conform
imaginii.
3) Modificm valoarea proprietii Caption a fiecrui buton de comand i cea
a formei conform imaginii.
4) Atribuim proprietii Text a casetei de editare valoare vid.
5) Prelucrm evenimentul OnClick al fiecrui buton de comand (la efectuarea
unui click pe unul din butoanele 0 .. 9 este necesar adugarea valorii butonului
n caseta de editare).
6) Deoarece datele iniiale snt de tip AnsiString, le vom transforma n numr,
le vom prelucra i apoi le vom transforma napoi n text pentru a le afia.
Pentru a exclude introducerea datelor greite din punct de vedere sintactic (se
accept doar cifre i caracterul .) vom prelucra evenimentul OnKeyPress a
casetei de editare.
7) Pentru a interzice scrierea caracterelor n cutia de editare se va seta
proprietatea ReadOnly la valoarea true.
- 34 -
- 35 -
Edit1->Clear();
Edit1->SetFocus();
}
void __fastcall TForm1::Button12Click(TObject *Sender){
Edit1->Clear();
Edit1->Text=AnsiString(eval(s));
s="";
Edit1->SetFocus();
}
void __fastcall TForm1::Button13Click(TObject *Sender){
Edit1->Clear();
s=s+"+";
Edit1->SetFocus();
}
void __fastcall TForm1::Button14Click(TObject *Sender){
Edit1->Clear();
s=s+"-";
Edit1->SetFocus();
}
void __fastcall TForm1::Button15Click(TObject *Sender){
Edit1->Clear();
s=s+"*";
Edit1->SetFocus();
}
void __fastcall TForm1::Button16Click(TObject *Sender){
Edit1->Clear();
s=s+"/";
Edit1->SetFocus();
}
void __fastcall TForm1::Button9Click(TObject *Sender){
Edit1->Text=Edit1->Text+"1";
s=s+"1";
Edit1->SetFocus();
}
void __fastcall TForm1::Button10Click(TObject *Sender){
Edit1->Text=Edit1->Text+"0";
s=s+"0";
Edit1->SetFocus();
}
void __fastcall TForm1::Button11Click(TObject *Sender){
Edit1->Text=Edit1->Text+".";
s=s+".";
}
void __fastcall TForm1::Button5Click(TObject *Sender){
Edit1->Text=Edit1->Text+"5";
s=s+"5";
Edit1->SetFocus();
}
void __fastcall TForm1::Button6Click(TObject *Sender){
Edit1->Text=Edit1->Text+"4";
- 36 -
s=s+"4";
Edit1->SetFocus();
}
void __fastcall TForm1::Button7Click(TObject *Sender){
Edit1->Text=Edit1->Text+"3";
s=s+"3";
Edit1->SetFocus();
}
void __fastcall TForm1::Button8Click(TObject *Sender){
Edit1->Text=Edit1->Text+"2";
s=s+"2";
Edit1->SetFocus();
}
void __fastcall TForm1::Button1Click(TObject *Sender){
Edit1->Text=Edit1->Text+"9";
s=s+"9";
Edit1->SetFocus();
}
void __fastcall TForm1::Button2Click(TObject *Sender){
Edit1->Text=Edit1->Text+"8";
s=s+"8";
Edit1->SetFocus();
}
void __fastcall TForm1::Button3Click(TObject *Sender){
Edit1->Text=Edit1->Text+"7";
s=s+"7";
Edit1->SetFocus();
}
void __fastcall TForm1::Button4Click(TObject *Sender){
Edit1->Text=Edit1->Text+"6";
s=s+"6";
Edit1->SetFocus();
}
void __fastcall TForm1::Button17Click(TObject *Sender){
Edit1->Clear();
Edit1->SetFocus();
}
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char
&Key)
{
switch(Key){
case '.' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
- 37 -
case
case
case
case
case
case
case
'9'
'0'
'+'
'-'
'*'
'/'
'='
:
:
:
:
:
:
:
Edit1->Text=Edit1->Text+Key;s=s+Key; break;
Button13Click(Sender);break;
Button14Click(Sender);break;
Button15Click(Sender);break;
Button16Click(Sender);break;
Button12Click(Sender);break;
}
}
- 38 -
- 39 -
Valoarea parametrului LB
MB_ABORTRETRYIGNORE
MB_OK
MB_OKCANCEL
MB_RETRYCANCEL
MB_YESNO
MB_YESNOCANCEL
- 40 -
Dac aceast fereastr va fi nchis prin tastarea tastei Retry, atunci se va afia
fereastra
- 41 -
Funcia InputQuery (S1, S2, S3) are efect similar funciei InputBox cu
deosebirea c textul din linia de editare se returneaz prin parametrul S3.
Valoarea returnat de funcie este de tip logic i este true doar n cazul cnd
fereastra a fost nchis prin apsarea tastei Ok. n caz contrar S3 primete
valoare vid. De exemplu, n urma executrii instruciunii
if (InputQuery("Date personale", "Numele", S))
Label1->Caption = S;
Eticheta Label1 va afia textul din caseta de editare a ferestrei doar dac
utilizatorul va apsa butonul Ok.
- 42 -
Exemplu rezolvat
S crem o aplicaie MDI cu 3 ferestre. La efectuarea unui click pe
fereastra principal (fereastra printe), ferestrele subordonate vor fi aranjate una
lng alta n interiorul ferestrei principale. La efectuarea unui click pe o fereastr
subordonat, toate ferestrele vor fi aranjate sub form de casccad.
Realizare
1) Includem 3 forme n proiect (Form1 forma principal, Form2 i Form3
forme subordonate).
2) Modificm proprietatea Caption a fiecrei forme ( vezi fig.1).
3) Prelucrm evenimentul OnClick al fiecrei forme.
4) Salvm i lansm aplicaia la execuie.
- 43 -
- 44 -
- 45 -
- 46 -
- 47 -
- 48 -
- 49 -
La selectarea unui buton radio n caseta Edit1 va aprea numele lui. Un click
pe una din tastele butonului de incrementare/decrementare va mri sau va
micora valoarea din caseta Edit3. Caseta Edit2 va afia starea butonului de
opiune.
Realizare
1) Executm File\New\Other.
2) Plasm pe form componentele conform enunului.
3) Modificm proprietatea Caption a formei, a etichetei, a butonului de opiune
conform enunului. Crem butoanele radio cu ajutorul proprietii Items a
componentei RadioGroup1.
4) Proprietii Asociate a butonului de opiune i atribuim valoarea Edit3.
5) Prelucrm evenimentul OnClick al butonului de opiune i cel al componentei
RadioGroup1.
6) Salvm i lansm aplicaia la execuie.
- 50 -
- 51 -
- 52 -
Exemplu rezolvat
S elaborm o aplicaie care va determina toi divizorii unui numr
natural. Pentru a citi valoarea numrului va fi utilizat o cutie de editare, iar
pentru afiarea rezultatului o zon de editare. Butonul Determin Divizorii va
calcula i va afia n zon divizorii numrului. Butonul Salveaza va salva
rezultatul ntr-un fiier, a crui nume va fi specificat de utilizator.
Realizare:
1) Plasm controalele necesare pe suprafaa formei.
- 53 -
- 54 -
- 55 -
- 56 -
Exemple rezolvate
1. S crem o aplicaie cu dou ferestre. Prima fereastr va avea
urmtoarele meniuri:
File
Forma Noua
Inchide
View
Mica
Marime Mijlocie
Mare
Verde
Culoare Rosu
Albastru
Meniul principal
Inaltime
Latime
100
200
300
100
200
300
Meniul contextual
- 57 -
Realizare:
1) Executm File\New\Application.
2) Executm File\New\Form. Atribuim proprietii Visible a formei Form2
valoarea false.
3) Plasm componentele MainMenu i PopupMenu pe form.
4) Lansm utilitarul de proiectare a meniurilor executnd un click n caseta de
valori a proprietii Items a fiecrei componente. Scriem elementele de meniu
conform enunului.
5) Atribuim proprietii PopupMenu a formei valoarea PopupMenu1.
6) Prelucrm evenimentul OnClick al fiecrui element de meniu.
7) Salvm i lansm aplicaia la execuie.
- 58 -
}
void __fastcall TForm1::Inchide1Click(TObject *Sender){
Form1->Close();
}
void __fastcall TForm1::Mica1Click(TObject *Sender){
Form1->Width=50; Form1->Height=50;
}
void __fastcall TForm1::mijlocie1Click(TObject *Sender){
Form1->Width=200; Form1->Height=200;
}
void __fastcall TForm1::Mare1Click(TObject *Sender){
Form1->Width=400; Form1->Height=400;
}
void __fastcall TForm1::Verde1Click(TObject *Sender){
Form1->Color=clGreen;
}
void __fastcall TForm1::Galben1Click(TObject *Sender){
Form1->Color=clRed;
}
void __fastcall TForm1::Albastru1Click(TObject *Sender){
Form1->Color=clBlue;
}
void __fastcall TForm1::N1001Click(TObject *Sender){
Form1->Height=100;
}
void __fastcall TForm1::N2001Click(TObject *Sender){
Form1->Height=200;
}
void __fastcall TForm1::N3001Click(TObject *Sender){
Form1->Height=300;
}
void __fastcall TForm1::N1002Click(TObject *Sender){
Form1->Width=100;
}
void __fastcall TForm1::N2002Click(TObject *Sender){
Form1->Width=200;
}
void __fastcall TForm1::N3002Click(TObject *Sender){
Form1->Width=300;
}
- 59 -
Iesire
- 60 -
- 61 -
AnsiString s1,s2,s3,s4,sir;
int i;
s1=AnsiString(nume);
for(i=s1.Length();i<21;i++) s1=s1+"
";
s2=AnsiString(prenume);
for(i=s2.Length();i<21;i++) s2=s2+"
";
s3=AnsiString(grupa);
for(i=s3.Length();i<16;i++) s3=s3+"
";
s4=AnsiString(media);
for(i=s4.Length();i<11;i++) s4=s4+"
";
sir=s1+s2+s3+s4;
return sir;
}
void lista::creare(){
student *p;
while(!f.eof()){
p=new student;
p->citire();
if(prim==NULL){prim=l=p;}
else{l->next=p;l=p;}
}
}
void lista::afisare(){
l=prim;
while(l->next!=NULL){
Form1->Memo1->Lines->Add(l->linie());
l=l->next;
}
}
void lista::lenesi(){
l=prim;
while(l->next!=NULL){
if(l->media<=6) Form1->Memo1->Lines->Add(l->linie());
l=l->next;
}
}
void lista::eminenti(){
l=prim;
while(l->next!=NULL){
if(l->media>=8.88) Form1->Memo1->Lines->Add(l->linie());
l=l->next;
}
}
lista::~lista(){
while(prim!=NULL){
l=prim;
prim=prim->next;
delete l;
}
}
- 62 -
lista p;
void __fastcall TForm1::Iesire1Click(TObject *Sender){
Application->Terminate();
}
void __fastcall TForm1::FormCreate(TObject *Sender){
p.creare();
}
void __fastcall TForm1::Totistudentii1Click(TObject *Sender){
Memo1->Clear(); p.afisare();
}
void __fastcall TForm1::Studentilenesi1Click(TObject *Sender){
Memo1->Clear(); p.lenesi();
}
void __fastcall TForm1::Studentieminenti1Click(TObject
*Sender){
Memo1->Clear(); p.eminenti();
}
void __fastcall TForm1::Button1Click(TObject *Sender){
Memo1->Clear();
}
- 63 -
struct TRect {
TRect() {}
TRect(const TPoint& TL, const TPoint& BR) {
left=TL.x; top=TL.y; right=BR.x; bottom=BR.y;
}
- 64 -
struct TPoint {
TPoint() {}
TPoint(int _x, int _y) : x(_x), y(_y) {}
TPoint(POINT& pt) { x=pt.x; y=pt.y; }
}
Arc (X1, Y1, X2, Y2, X3, Y3, X4, Y4) construiete un segment de elips
nscris n dreptunghiul determinat de coordonatele ntregi X1, Y1, X2, Y2
i mrginit de semidreptele cu originea n centrul dreptunghiului i care trec
prin punctele (X3, Y3), (X4, Y4). Se deseneaz mpotriva acelor de ceas.
Chord (X1, Y1, X2, Y2, X3, Y3, X4, Y4) construiete o elips nscris n
dreptunghiul determinat de coordonatele ntregi X1, Y1, X2, Y2, domeniul
- 65 -
Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4) construiete un sector de elips
nscris n dreptunghiul determinat de coordonatele X1, Y1, X2, Y2 i
mrginit de semidreptele cu originea n centrul dreptunghiului i care trec
prin punctele (X3, Y3), (X4, Y4). Se deseneaz mpotriva acelor de ceas.
- 66 -
RoundRect (X1, Y1, X2, Y2, X3, Y3: Integer) construiete i coloreaz
un dreptunghi cu colurile rotunjite, a crui diagonal este mrginit de
punctele (X1, Y1), (X2, Y2).
- 67 -
TryLock (de tip bool) returneaz valoarea true dac pnza de desenare nu
este blocat de alte comenzi, apoi o blocheaz.
Center (de tip bool) stabilete dac centrul imaginii afiate de component
va coincide (pentru valoarea true) sau nu cu centrul ei. n cazul valorii
false, colul stnga-sus al imaginii va fi poziionat n colul-stnga sus al
componentei. Proprietatea Center nu are nici un efect atunci, cnd
proprietatea AutoSize are valoarea true, sau atunci cnd proprietatea Stretch
este true i proprietatea Picture nu specific un simbol grafic de extensie
*.ICO.
- 68 -
Exemple rezolvate
1. S crem o aplicaie care va desena pe fereastra aplicaiei un disc n poziia n
care utilizatorul va efectua un click de mouse. Meniul contextual al aplicaiei va
conine comenzile Curata i Inchide pentru curirea ferestrei i respectiv
pentru nchiderea aplicaiei. De asemenea, la apsarea tastei x aplicaia va fi
nchis. Pentru determinarea poziiei mouse-lui vom folosi expresiile:
Mouse->CursorPos.x returneaz coordonata x;
Mouse->CursorPos.y returneaz coordonata y.
Realizare
1) Executm File\New\Application. Plasm pe form o component de tip
TPopupMenu.
2) Prelucrm evenimentele OnClick i OnKeyPress ale formei.
3) Modificm proprietatea Caption a formei. Scriem elementele meniului
contextual i prelucrm evenimentul OnClick al fiecrui element de meniu.
4) Salvm i lansm aplicaia la execuie.
- 69 -
- 70 -
- 71 -
x=x+0.001;
}}
void __fastcall TForm1::FormResize(TObject *Sender){
double x,y;
int x1, y1;
Form1->Canvas->Pen->Width=1;
Canvas->Rectangle(0,0, ClientWidth, ClientHeight);
Color=clWhite;
Canvas->MoveTo(ClientWidth /2,0);
Canvas->LineTo(ClientWidth / 2, ClientHeight);
Canvas->MoveTo(0, ClientHeight / 2);
Canvas->LineTo(ClientWidth, ClientHeight / 2);
Canvas->TextOut(ClientWidth-10, ClientHeight / 2 + 2, "X");
Canvas->TextOut(ClientWidth / 2 + 20, ClientHeight / 2, "1");
Canvas->TextOut(ClientWidth / 2 + 2, 5, "Y");
Canvas->TextOut(ClientWidth / 2 + 2, ClientHeight / 2 - 20,
"1");
Form1->Canvas->Pen->Width=3;
x=-5;
while (x<=5) {
y=x*x*x;
x1=20*x+ ClientWidth / 2;
y1=ClientHeight / 2-20*y;
Canvas->Pixels[x1][y1]=clRed;
x=x+0.001;
}}
. Efecte de animaie
- 72 -
Exemplu rezolvat
S crem o aplicaie a crei fereastr va conine dou butoane de
comand (Start i Stop). Butonul Start va lansa un proces care va desena n
poziii aleatoare discuri de culori aleatorii la fiecare 0,5 secunde. Butonul Stop
va ntrerupe procesul.
Realizare:
1) Executm File / New /Application.
2) Plasm pe form dou butoane de comand i o component de tip
TTimer.
3) Atribuim proprietii Caption a butoanelor de comand valori
conform enunului.
4) Prelucrm evenimentul OnTimer al componentei Timer1 i
evenimentul OnClick al fiecrui buton de comand.
5) Lansm aplicaia la execuie.
- 73 -
- 74 -
- 75 -
- 76 -
i TSavePictureDialog
- 77 -
, PrinterSetupDialog
se utilizeaz similar.
Exemple rezolvate
1. S crem o aplicaie a crei fereastr va conine dou butoane de comand:
unul va ncrca coninutul unui fiier ntr-o zon de editare, cellalt va salva
coninutul zonei ntr-un fiier.
Realizare:
1) Executm File / New /Application.
2) Plasm pe form dou butoane de comand i cte o component de tip
TMemo, TSaveDialog i TOpenDialog. Modificm valorile proprietilor
Caption ale butoanelor de comand.
- 78 -
Edit
Copy
Paste
Select All
- 79 -
Font
Realizare:
1) Executm File / New /Application.
2) Plasm pe suprafaa formei trei cutii de dialog (OpenDialog1, SaveDialog1,
FontDialog1), o zon de editare (Memo1), un meniu principal (MainMenu1).
Crem elementele meniului principal.
3) Prelucrm evenimentul OnClick al fiecrui element de meniu.
4) Aa cum la redimensionarea ferestrei aplicaiei, dimensiunile zonei de
editare trebuie s fie racordate cu dimensiunile acestei ferestre, prelucrm
evenimentele OnResize i OnShow ale formei.
5) Lansm aplicaia la execuie.
- 80 -
}
void __fastcall TForm1::FormResize(TObject *Sender){
Memo1->Top=0;
Memo1->Left=0;
Memo1->Height=Form1->Height-55;
Memo1->Width=Form1->Width-10;
}
void __fastcall TForm1::SaveAs1Click(TObject *Sender){
SaveDialog1->Execute();
Memo1->Lines->SaveToFile(SaveDialog1->FileName);
}
void __fastcall TForm1::Open1Click(TObject *Sender){
OpenDialog1->Execute();
Memo1->Lines->LoadFromFile(OpenDialog1->FileName);
}
void __fastcall TForm1::New1Click(TObject *Sender){
int i=Application->MessageBoxA("Doriti sa salvati
fisierul","Save", MB_YESNO);
if(i==IDYES){
OpenDialog1->Execute();
Memo1->Lines->SaveToFile(SaveDialog1->FileName);
}
Memo1->Clear();
}
void __fastcall TForm1::Close1Click(TObject *Sender){
Form1->Close();}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction
&Action){
int i=Application->MessageBoxA("Doriti sa salvati
fisierul","Save", MB_YESNO);
if(i==IDYES){
OpenDialog1->Execute();
Memo1->Lines->SaveToFile(SaveDialog1->FileName);
}
}
void __fastcall TForm1::Copy1Click(TObject *Sender){
Memo1->CopyToClipboard();
}
void __fastcall TForm1::Paste1Click(TObject *Sender){
Memo1->PasteFromClipboard();
}
void __fastcall TForm1::SelectAll1Click(TObject *Sender){
Memo1->SelectAll();}
void __fastcall TForm1::Font1Click(TObject *Sender) {
FontDialog1->Execute();
Memo1->Font=FontDialog1->Font;
}
- 81 -
- 82 -
Exemplu rezolvat
Fereastra urmtoarei aplicaii va conine:
- o caset de editare n care vom scrie un text;
- o list de opiuni n care se va aduga cte o opiune textul din caseta
de editare;
- 83 -
Realizare:
1) Executm File / New /Application.
2) Plasm pe form componentele conform enunului.
3) Prelucrm evenimentul OnClick al fiecrui buton de comand.
3) Modificm proprietatea Caption a formei i a butoanelor de comand.
4) Apsm F9 pentru compilarea i executarea programului.
- 84 -
if (!(ListBox1->ItemIndex == -1))
ListBox1->Items->Delete(ListBox1->ItemIndex);
}
void __fastcall TForm1::Button1Click(TObject *Sender){
ListBox1->Items->Add(Edit1->Text);
Edit1->Clear();
}
void __fastcall TForm1::Button3Click(TObject *Sender){ Close();
}
void __fastcall TForm1::Button4Click(TObject *Sender){
ShowMessage(ListBox1->Items->Strings[ListBox1->ItemIndex]);
}
- 85 -
- 86 -
- 87 -
permite editarea.
Unele evenimente ale clasei TStringGrid
OnColumnMoved apare atunci cnd este modificat poziia coloanelor.
OnDrawCell se declaneaz n momentul n care trebuie desenat o celul
a reelei.
- 88 -
Exemplu rezolvat
S crem o aplicaie care va efectua adunarea a dou matrice ptratice
de ordinul 4. Vom folosi pentru stocarea matricelor i a rezultatului trei
componente de tip TStringGrid. Butonul de comand Genereaz elementele
(Button1) va genera aleator elementele celor dou matrice cu ajutorul funciei
random, iar butonul Calculeaza suma va calcula matricea-sum.
Realizare:
1) Executm File / New /Application.
2) Plasm pe form componentele conform enunului.
3) Atribuim proprietilor FixedCols i FixedRows ale fiecrei componente de
tip TStringGrid valoarea 0.
5) Modificm proprietatea Caption a formei i a butoanelor de comand.
6) Prelucrm evenimentul OnClick al fiecrui buton de comand
7) Apsm F9 pentru compilarea i executarea programului.
- 89 -
- 90 -
de zile care preced data menionat. Partea fracionar semnific fraciuni din
ziua corespunztoare valorii.
De exemplu, numrul 2.75 reprezint data 1 ianuarie 1900 ora 18:00, iar
numrul 3.25 data 27 decembrie 1899 ora 6:00.
Formatul de reprezentare a datei printr-un string depinde de opiunile
regionale stabilite n Windows. De exemplu, noi folosim formatul dd.MM.yy.
H:mm:ss, unde dd este numrul zilei n lun, MM numrul lunii, yy anul,
H ora, mm numrul minute, ss numrul de secunde.
Dac utilizatorul nu specific ora, minutele sau secundele, atunci acestea
se consider nule.
- 91 -
- 92 -
- 93 -
- 94 -
Exemplu rezolvat
Se crem o aplicaie a crei fereastr va afia dou calendare (unul de
tip TMonthCalendar, altul de tip TDateTimePicker) i un ceas digital care va
arta timpul curent. Selectarea unei date n unul dintre calendare va selecta
aceeai dat n cellalt calendar.
- 95 -
Realizare:
1) Executm File / New /Application.
2) Plasm pe form cte o component de tip TMonthCalendar,
TDateTimePicker, TTimer i dou etichete
3) Prelucrm evenimentele OnTimer al componentei Timer1, OnCreate al
formei, OnClick al componentei MonthCalendar1 i OnChange al
componentei DateTimePicker1.
4) Modificm proprietatea Caption a formei i a etichetelor.
5) Apsm F9 pentru compilarea i executarea programului.
- 96 -
TDateTime d;
d=Time();
Label1->Caption=AnsiString(d);
}
void __fastcall TForm1::FormCreate(TObject *Sender){
Timer1->Enabled=true;
Timer1->Interval=100;
}
void __fastcall TForm1::MonthCalendar1Click(TObject *Sender){
DateTimePicker1->Date=MonthCalendar1->Date;
}
void __fastcall TForm1::DateTimePicker1Change(TObject *Sender){
MonthCalendar1->Date=DateTimePicker1->Date;
}
- 97 -
de cutie.
FileEdit (de tip TEdit) stabilete cutia de editare care va afia numele
fiierului selectat de utilizator n cutie.
FileName (de tip AnsiString) pstreaz numele (mpreun cu calea)
fiierului selectat de utilizator n cutie.
FileType (de tip mulime) determin ce tip de fiiere va afia cutia. Valori
posibile: ftReadOnly, ftHidden, ftSystem, ftVolumeID, ftDirectory, ftArchive,
ftNormal.
Mask specific care fiiere pot fi afiate, asemeni proprietii Filter a
componentei OpenDialog.
ShowGlyphs (de tip bool) stabilete dac n faa fiecrui fiier va aprea
(pentru valoarea true) sau nu va aprea pictograma.
21.2. DirectoryListBox
Componenta DirectoryListBox (de tip TDirectoryListBox) este o cutie
care afieaz subcataloagele unei uniti de disc sau a unui catalog.
- 98 -
Exemplu rezolvat
S crem o aplicaie a crei fereastr va conine trei etichete (Atribute,
Nume fisier, Volum), un buton de comand (Cauta), apte butoane de validare
(fiecare caseta corespunde unui atribut de fiier), o caset de editare i un tabel
cu dou coloane (de tip TStringGrid). Utilizatorul va scrie n caseta de editare
numele unui fiier (sau o masc de fiier). Butonul Cauta va afia n tabel
denumirile i volumul fiierelor specificate de caset, care au atributele
butoanelor validate.
Realizare:
1) Executm File / New /Application.
2) Plasm pe form componentele conform enunului.
- 99 -
- 100 -
Exemplu rezolvat
S crem o aplicaie pentru a ilustra un mod de lucru cu directoare i
fiiere. Fereastra aplicaiei va conine patru etichete, un meniu principal
(MainMenu1) cu opiunile Creare (catalog), Sterge (catalog, fiier), un meniu
contextual (PopupMenu1) cu opiunea Sterge, cte o component de tip
TDirectoryListBox, TFileListBox, TEdit, TButton. Utilizatorul va putea viziona,
crea, terge cataloage.
- 101 -
Realizare:
1) Executm File / New /Application.
2) Plasm componentele pe form conform enunului. Modificm proprietatea
Caption a formei i a controalelor de pe form conform enunului. Atribuim
proprietii PopupMenu1 a componentei FileListBox1 valoarea PopupMenu1.
3) Pentru a crea legtura dintre componentele DirectoryListBox1 i
FileListBox1 atribuim valoarea FileListBox1 proprietii ListBox a controlului
DirectoryListBox1.
4) Prelucrm evenimentul OnClick al butonului de comand i al fiecrui
element de meniu.
5) Apsm F9 pentru compilarea i executarea programului.
- 102 -
- 103 -
- 104 -
Exemplu rezolvat
1. Pe supraa formei vor fi plasate urmtoare componete:
O cutie de editare, n cadrul creia utilizatorul va introduce numrul de
obiecte.
O cutie Label pentru afiarea rezultatului.
Trei componete TButton.
De elaborat o aplicaie care va permite utilizatorului s introduc un numr,
care s reprezinte numrul de cutii de tip TEdit. n aceste cutii utilizatorul va
introduce cte o valoare numeric. La efectuarea unui click pe butonul
determina suma, n Label1 va fi scris valoarea sumei, iar efectuarea unui click
pe butonul Distruge obiectele create, obiectele create vor disprea de pe form.
Realizare
Pentru comoditatea vor mai fi create dinamic i obiecte de tip TLabel,
Pentru a sugera utilizatorului introducerea valorilor numerice n cutiile TEdit
recent create
1) File/New/Application
2) Plasm componentele pe form, i modificm proprietatea caption (Fig.1)
- 105 -
- 106 -
Label[i]->Height = 23;
}
}
void __fastcall TForm1::Button3Click(TObject *Sender){
for(int i=0;i<n;i++) {
delete Edit[i] ;
delete Label[i];
}
delete Edit;
delete Label;
}
- 107 -
Fig.4
Aplicaia n execuie
Fiierul Unit1.cpp
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int n;
TEdit **Edit;
TForm *Forma;
TButton *Buton;
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}
void __fastcall TForm1::Button2Click(TObject *Sender){
Forma= new TForm(this);
Forma->Caption="Vector";
n=Edit1->Text.ToInt();
Edit = new TEdit *[n];
for(int i=0;i<n;i++){
Edit[i] = new TEdit(this);
Edit[i]->Parent = Forma;
Edit[i]->Top = 50;
Edit[i]->Left = 50+i*50;
Edit[i]->Width = 50;
Edit[i]->Height = 50;
Edit[i]->Text=AnsiString(random(100));
}
int max,min,p1,p2,y;
max=min=Edit[0]->Text.ToInt();
for(int i=1;i<n;i++){
y=Edit[i]->Text.ToInt();
if(max<y) {max=y;p1=i;}
if(min>y) {min=y;p2=i;}
}
Edit[p1]->Color=clMoneyGreen;
Edit[p2]->Color=clSkyBlue;
- 108 -
Forma->Show();
}
void __fastcall TForm1::Button1Click(TObject *Sender){
for(int i=0;i<n;i++) delete Edit[i];
delete Edit;
delete Forma;
}
- 109 -
Capitolul
II
- 110 -
3. Din meniul Object alegem comanda New. Apare fereastra New Database
Alias n care alegem tipul aliasului. Alegem STANDARD i apsm OK.
- 111 -
- 112 -
- 113 -
- 114 -
Validity Checks asigur o completare mai bun a datelor prin verificarea lor
dup urmtorii parametri:
Minimul value valoarea minim;
Maximum value valoarea maxim;
Default value valoarea implicit;
Picture specific tipul informaiei care urmeaz a fi plasat (creaz o
masc pentru introducerea datelor; de exemplu, masca [-]#*# permite
utilizatorului s scrie doar numere ntregi negative sau pozitive, iar
masca #*# doar a celor pozitive);
Butonul Assist... afieaz o fereastr prin care utilizatorul poate alege o
masc pentru caseta Picture.
Table Lookup permite introducerea valorilor n mas, folosind datele
existente dintr-un alt tabel.
Secondary Indexes este un index care permite sortarea datelor nu doar dup
cmpul cheie-primar. Cu ajutorul acestui index se poate indica:
o nou sortare a datelor;
cmpul, care poate lega tabelul cu alt tabel;
o metod de cutare.
Un tabel poate avea mai multe tipuri de index cum ar fi:
Unique interzice nregistrrile cu aceleai valori ntr-un anumit cmp;
Case Sensitive face diferen dintre majuscule i minuscule n timpul
sortrii;
Maintained (poate fi activat doar dac nu este activat Unique) reinoiete
indexul;
Descending stabilete sortarea descresctoare a nregistrrilor.
Referential Integrity stabilete proprietile relaiei dintre dou tabele. ntre
dou tabele de tip paradox poate fi creat o relaie Parinte Copil, unde
tabelul de tip Copil primete datele de la tabelul Printe.
Password Security creeaz parole pentru protejarea tabelului de un acces
neautorizat.
- 115 -
- 116 -
unde V este o
- 117 -
- 118 -
Table1.
3. Atribuim proprietii DataSource a componentei DBGrid1 valoarea
DataSource1.
4. Stablim valoarea true pentru proprietatea Active a controlului Table1.
Observaie. Evident, proprietile DatabaseName
componentei Table1 au fost setate n prealabil.
TableName
ale
First
Prior
Next
Last
Insert
Delete
terge nregistrarea curent i poziioneaz cursorul pe
urmtoarea nregistrare.
- 119 -
Edit
Post
Cancel
Refresh
Exemplu rezolvat
S crem un tabel de tip Paradox (avnd numele Muncitori) cu
urmtoarea cmpuri:
Numele cmpului
Nume
Prenume
Anul_ang
Categoria
Sal_Calculat
Impozite
Sal_Primit
Tipul cmpului
ir de caractere (Alpha)
ir de caractere (Alpha)
Numeric (Number)
Numeric (Number)
Numeric (Number)
Numeric (Number)
Numeric (Number)
- 120 -
- 121 -
- 122 -
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}
void __fastcall TForm1::Button1Click(TObject *Sender){
double sc,imp,iv,fs,am;
int cat,anul,ore,zile;
ore=8; zile=24;
Table1->First();
while(!Table1->Eof)// cit timp nu sntem la ultima
inregistrare
{
cat=Table1->FieldValues["Categoria"];
anul=Table1->FieldValues["Anul_Ang"];
switch(cat) {
case 1: sc=1.2*ore*zile; break;
case 2: sc=1.5*ore*zile; break;
case 3: sc=1.8*ore*zile; break;
}
if(anul_curent-anul>=15)
sc+=sc*0.2;
else if(anul_curent-anul>=5)
sc+=sc*0.1;
iv=sc*0.08;
fs=sc*0.05;
am=sc*0.04;
Table1->Edit();//Pregateste tabelul pentru a inscrie date
Table1->FieldValues["Sal_Calculat"]=sc;
Table1->FieldValues["Impozite"]=fs+am+iv;
Table1->FieldValues["Sal_Primit"]=sc-fs-am-iv;
Table1->Post();//Salveaza modificarele efectuate in tabel
Table1->Next();//trece la urmatoarea inregistrare
}
}
DBText
este un control asemeni etichetei Label. Prin intermediul
proprietii DataSource poate fi creat legtura dintre acest control i
un tabel sau o interogare. Dup crearea legturii n proprietatea
DataField se indic cmpul, a crui informaie va fi afiat de
componenta DBText.
- 123 -
DBEdit
este un control asemeni casetei de editare Edit. Se poate
folosi pentru afiarea sau pentru editarea datelor unui cmp al unei surse
de date. Modalitatea de lucru este similar cu a controlului DBText.
DBMemo
este un control asemeni zonei de editare Memo.
Modalitatea de lucru este similar cu a controlului DBText. DBMemo
este utilizat deseori pentru prezentarea informaiei din cmpurile care
conin un volum mai mare de informaie.
DBImage
este un control asemeni componentei Image. Este utilizat
pentru reprezentarea imaginilor unei baze de date.
DBListBox
reprezint o list asemeni controlului ListBox.
Coninutul listei este valoarea proprietii Items (de tip TStrings).
Astfel, pentru a aduga n lista DBListBox1 informaia din cmpul
Virsta al tabelului Table1 se vor scrie instruciunile:
while(!Table1->Eof){
DBListBox1->Items->Add(AnsiString(Table1->
FieldValues["Virsta"]));
Table1->Next();
};
DBComboBox
este un control asemeni casetei combinate
ComboBox. Modalitatea de lucru este similar cu a componentei
DBListBox.
DBCheckBox
este un control asemeni casetei de validare
CheckBox i, de regul, este utilizat pentru afiarea valorilor unui cmp
de tip logic.
DBRadioGroup
- 124 -
DBLookupListBox
nregistrrilor
DBLookupComboBox
DBLookupListBox.
DBRichEdit
DBMemo.
DBChart
este un control pentru crearea diagramelor pe baza
informaiei tabelelor unei baze de date (modalitatea de creare este
asemntoare cu cea din Microsoft Excel).
Exemple rezolvate
1. S elaborm o aplicaie prin intermediul creia utilizatorul va putea
modifica cmpul Categoria al tabelulului Muncitori (creat n paragraful
anterior). n cmpul Categoria pot fi introduse valori de la 1 la 5.
Realizare:
Pentru prezentarea informaiei din tabel vor fi utilizate componente de
tip DBText, iar pentru navigarea datelor tabelului va fi utilizat o component
de tip TDBNavigator. Prin intermediul butonului Post i a componentei de tip
TDBListBox, va fi posibil modificarea cmpului Categoria. n cadrul
proprietii Items a componentei vor fi introduse valori de la 1 la 5.
1. Considerm aliasul i tabelul Muncitori create, iar componentele Table1 i
DataSourse1 plasate pe form (vezi 1 i exemplul rezolvat din 2), precum
i setate proprietatea DataSet a componentei DataSourse1 i proprietatea
Active a componentei Table1.
2. Plasm pe form 5 componente de tip TDBText, cte o component de tip
TDBListBox, TDBNavigator.
3. Crem legtura ntre surs i controlul DBNavigator1: atribuim proprietii
DataSourse a componentei DBNavigator1 valoarea DataSourse1.
- 125 -
- 126 -
Realizare:
1. Considerm create aliasul i tabelele Muncitori i Locuinta, iar
componentele Table1, Table1, DataSourse1, DataSourse2, TDBText1,
TDBText2, TDBText3 plasate pe form (vezi 1 i exemplul rezolvat din 2),
precum i setate proprietatea DataSet ale componentelor DataSourse1,
DataSourse2, proprietatea Active ale componentelor Table1, Table2,
proprietile DataField i DataSourse ale componentelor de tip TDBText.
2. Plasm pe form o component de tip TDBLookupComboBox.
3. Crem relaia ntre tabele (dup cmpul NrOrdine) prin intermediul
componentei DBLookupComboBox1. Setm proprietile componentei
DBLookupComboBox1 astfel:
DataSource=DataSource1
DataField=NrOrdine
ListSource= DataSource1
KeyField= NrOrdine
ListField=Adresa
4. Salvm i lansm aplicaia la execuie.
- 127 -
6. ndicm sursa (tabelul din care vor fi extrase datele): din paleta Series
alegem pagina DataSource, iar de aici DataSet. Efectum modificrile
necesare.
- 128 -
- 129 -
4. Interogri
Interogarea este un obiect, prin intermediul cruia din baza de date se
extrag nregistrri, care corespund condiiilor indicate. Cu ajutorul interogrilor
se pot vizualiza, analiza i modifica datele din tabele. Pentru crearea
interogrilor, BCB ofer componenta Query, care se afl pe paleta DBE.
Interogrile se scriu n limbajul SQL.
- 130 -
- 131 -
Exemplu rezolvat
S elaborm o aplicaie care va permite efectuarea urmtoarelor
interogri pentru tabelul Muncitori (creat un exemplele precedente):
- Afiarea muncitorilor cu salariu mai mare dect 300 (de uniti
convenionale);
- Afiarea muncitorilor cu salariu mai mic dect 300;
- Afiarea muncitorilor angajai pn n 1990;
- Afiarea muncitorilor angajai dup 1990;
- Afiarea tuturor muncitorilor.
Realizare:
1. Considerm aliasul i tabelul Muncitori create, iar componentele Table1 i
DataSourse1 plasate pe form (vezi 1 i exemplul rezolvat din 2), precum
i setate proprietatea DataSet a componentei DataSourse1 i proprietatea
Active a componentei Table1.
- 132 -
proprietile
- 133 -
5. Rapoarte
Un raport reprezint o modalitate de extragere a unei informaii din BD
cu scopul ca ulterior aceasta s fie tiprit.
Prin sursa unui raport vom nelege un tabel sau o interogare.
Pentru crearea rapoartelor BCB ofer paleta de componente QReport.
Vom examina unele componente ale acestei palete.
- 134 -
- 135 -
fi
configurat
prin
intermediul
Exemplu rezolvat
Vom crea un raport pe baza tabelului Muncitori (utilizat mai sus).
Realizare:
1. Considerm aliasul i tabelul Muncitori create, iar componentele Table1 i
DataSourse1 plasate pe form (vezi 1 i exemplul rezolvat din 2), precum
i setate proprietatea DataSet a componentei DataSourse1 i proprietatea
Active a componentei Table1.
2. Plasm pe form cte un control de tip TButton (pentru viualizarea prealabil
a raportului) i TQuickRep.
3. Atribuim proprietii DataSet a controlului QuickRep valoarea Table1.
4. Plasm 4 componente de tip TQRLabel i 4 componente de tip TQRDBText.
Setm proprietile DataSet i DataField a fiecrei dintre componentele
QRDBText (vezi imaginea), precum i proprietatea Caption a fiecrei dinte
componentele QRLabel.
- 136 -
- 137 -
6. Tehnologia ADO
Microsoft ADO (ActiveX Data Objects) asigur acces aplicaiilor client
la date. Pentru implementarea modelului ADO Borland C++ Builder ofer
paleta de componente ADO, cu ajutorul creia se poate realiza conectarea la
sursele de date suportate de ADO. S examinm componentele acestei palete.
Componenta ADOConnection (de tip TADOConnection) se utilizeaz
pentru conectarea la baza de date. Mai multe seturi de date pot folosi n comun
aceast conexiune pentru extragerea datelor i pentru executarea comenzilor.
Componenta ADOCommand (de tip TADOCommand) execut comenzi
SQL care nu genereaz date. Poate fi folosit cu o alt component ADO de tip
TDataSet.
Componenta ADODataSet (de tip TADODataSet) se folosete pentru
extragerea i operarea datelor din una sau mai multe tabele. Conexiunea se
poate face direct cu sursa de date sau printr-o component de tip
TADOConnection.
Componenta ADOTable (de tip TADOTable) reprezint un set de date sub
form de tabel folosit pentru extragerea i operarea unui set de nregistrri
produs de o singur tabel din BD. Poate fi conectat direct cu sursa de date
sau poate folosi o conexiune existent.
Componenta ADOQuery (de tip TADOQuery) este un set de date de tip
interogare care poate extrage un set de nregistrri bazat pe o comand valid
SQL. Conexiunea se poate face direct cu sursa de date sau printr-o component
de tip TADOConnection..
Componenta ADOStoredProc (de tip TADOStoredProc) se folosete
pentru execuia funciilor stocate care pot sau nu s genereze date.
- 138 -
- 139 -
a proprietii ConnectionString.
- 140 -
- 141 -
- 142 -
- 143 -
10. Apare fereastra ODBC Microsoft Access Setup. Apsm butonul Select.
12. Alegem baza de date i efectum un click pe butonul OK. Din acest
moment conexiunea cu baza de date este creat.
Dup stabilirea conexiunii pot fi utilizate componentele pentru
prelucrarea informaiei din baza de date.
- 144 -
Exemplu rezolvat
Considerm tabelul Autori al bazei de date Biblioteca, creat cu MS
Access. S crem o aplicaie care va afia datele dintru-un tabel MS Access.
Realizare:
1. Plasm pe form cte o component de tip TADOConnection, TADOTable
(de pe paleta ADO), TDataSource (de pe paleta Data Acess), TDBGrid (de pe
paleta Data Controls).
2. Atribuim proprietilor Connection i TableName ale componentei
ADOTable1 respectiv valorile ADOConection1 i Autori.
3. Atribuim valoarea ADOTable1 proprietii DataSet a componentei
DataSource1.
4. Atribuim proprietii DataSource a controlului DBGrid1 valoarea
DataSource1.
5. Stabilim proprietii Active a componentei ADOTable1 valoarea true.
6. n DBGrid1 vor aprea datele din tabelul Autori.
- 145 -
- 146 -
10. Indroducem datele despre adresa bazei de date. n caseta Server scriem
numele serverului pe care se afl baza de date (localhost serverul local).
11. n caseta User indicm numele user-ului pe care lucrm (nu este un account
al bazei de date).
12. n cazul n care user-ul este protejat cu parol, aceasta se indic n caseta
Password.
13. Dac datele au fost introduse corect, atunci n lista derulant Database apar
numele bazelor de date existente (n imagine, information_schema, mysql).
Dup selecrarea numelui bazei de date se efectueaz un click pe butonul Ok.
14. Se confirm numele conexiunii n fereastra Select Data Source. Din acest
moment conexiunea este efectuat.
15. Pentru prelucrarea bazei de date urmeaz a fi plasate i configurate
componentele necesare.
- 147 -
Capitolul III
Programarea Orientat
pe Obiecte cu C++
1. Preliminarii
Orice limbaj de programare se bazeaz pe o anumit ideee dominant,
care determin structura programelor create cu acest limbaj.
Din punct de vedere istoric iniial a dominat idea structurrii
procedurale a programelor. Programatorul decidea ce proceduri va utiliza n
program, apoi alegea cel mai potrivit algoritm pentru realizarea acestor
proceduri. De exemplu, limbajul Fortran este un limbaj de programare
procedural. Acest tip de programare a dus la crearea bibliotecilor mari de
proceduri.
Pe parcursul dezvoltrii informaticii accentul s-a deplasat de la
proceduri spre organizarea datelor. S-a ajuns la concluzia c pentru elaborarea
programelor eficace era nevoie de utilizarea corect a datelor. Ca o consecin
logic a noii tendine, a aprut ideea structurrii programelor cu ajutorul
modulelelor (adic a unitilor de program). n ele erau stocate nu doar
subprograme, dar i date. De exemplu, limbajul Pascal este un limbaj de
programare modular.
Ideea dominant a programrii moderne, numit Programare
Orientat pe Obiecte (POO), presupune unirea datelor cu subprogramele care
prelucreaz aceste date ntr-un tot ntreg, numit obiect. Aceast aciune (de
unire) se numete incapsulare, iar subprogramele unui obiect metode. La
incapsulare se ia n considerare legtura logic dintre date i metode.
De fapt, concepia de obiect a intervenit pentru crearea unor noi tipuri
de date, care nu snt predefinite (de exemplu, tipurile de date numr complex i
graf nu snt definite n majoritatea limbajelor dfe programare). Aa cum un tip
de date este definit nu doar de mulimea valorilor tipului (adic de datele
propriu zis), dar i de operatorii aplicabili asupra acestor valori, a aprut ideea
incapsulrii datelor i metodelor. Pe parcursul timpului, sensul atribuit
- 148 -
2. Clase
Aa cum clasa este un tip abstract de date, rezult c ea este format din
dou pri:
a) partea care definete datele, componentele ei fiind numite date
membru;
b) partea care definete operaiile asupra datelor, format din
subprograme, numite funcii membru.
Clasele de baz se declar cu ajutorul cuvntului-cheie class, conform
urmtoarei diagrame de sintax:
- 149 -
- 150 -
- 151 -
3. Pointerul *this
Orice metod apelat a unui obiect are definit implicit pointerul
this, a crui valoare este adresa obiectului. El nu poate fi declarat explicit, nu
poate fi modificat, dar poate fi utilizat explicit.
Exemplu:
class complex {
public:
double re,im;
void init(double x,double y);
};
void complex::init(double x,double y)
{
this->re = x;
this->im = y;
}
4. Funcii inline
La compilare operaiile suplimentare de apel a unei funcii inline i de
revenire din ea snt eliminate. O metod definit (nu doar declarat) n
interiorul clasei este implicit metod inline.
O metod definit n fara clasei se consider metod inline doar dac n
locul unde ea este definit antetul metodei este prefixat de cuvntul cheie inline.
De exemplu, metoda citire() a clasei vector poate fi definit metod
inline astfel:
inline void vector::citire(){for(int i=0;i<N;i++)
cin>>vect[i];}
Observaii
1. Este interzis folosirea n cadrul funciilor inline a structurilor repetitive (for,
while, do while),
i a funciilor recursive.
2. De regul, o metod inline conine n definirea ei pn la 45 instruciuni.
3. De regul, metodele inline nu conin n definirea lor operaii aritmetice.
- 152 -
5. Constructor
Constructorul este o funcie-membru special care are ca scop principal
iniializarea obiectelor. Se pot defini civa constructori pentru aceeai clas. Ei
vor fi funcii suprancrcate (vom examina suprancrcarea mai trziu) i se
vor deosebi prin numrul i/sau tipurile parametrilor. Constructorii respect
urmtoarele reguli:
1. Au acelai nume ca i clasa pentru care snt definii.
2. Constructorii nu returneaz nimic.
3. Constructorii pot fi suprancrcai.
4. Constructorii se apeleaz automat la crearea unui obiect al clasei (se mai
spune la instanierea obiectului).
De regul, constructorii snt apelai:
a) la declararea de obiecte sau la crearea dinamic de obiecte n care se
prevd iniializri cu variabile sau obiecte de tipul/clasa parametrilor
constructorului;
b) la convertirea unor constante sau variabile de alt tip la tipul clasei
respective.
Exemplu:
class complex {
public:
double re,im;
complex(double a, double b){re=a;im=b;} // def. constructorului
};
main(){
complex X(2.4,5.8); // instantierea obiectului X
}
- 153 -
- 154 -
6. Destructor
Destructorul este o funcie-membru special care are ca scop principal
distrugerea obiectului (deci eliberarea memoriei ocupat de acest obiect). Un
obiect se distruge n una din urmtoarele trei situaii:
cnd este prsit blocul n care a fost creat (cazul obiectelor locale);
la terminarea programului (cazul obiectelor globale);
cnd se aplic operatorul delete (obiecte create dinamic cu new).
n cazul n care nu este definit explicit un destructor, compilatorul genereaz
automat unul cu corpul de instruciuni vid. Destructorul nu are parametri i nu
returneaz nimic. O clas are un unic destructor, care nu poate fi suprancrcat
(deoarece nu are parametri). Numele destructorului se formeaz din numele
clasei precedat de simbolul "~" (tilda). Destructorul se apeleaz automat la
distrugerea unui obiect al clasei.
Exemplu rezolvat
1. S crem clasa student cu datele membru nume, nr_de_identificare,
cursul, media i metodele tipareste_student(), bursa(). Vom descrie toate
tipurile de constructori pentru aceast clas.
Realizare:
#include <conio.h>
#include <string.h>
#include <iostream.h>
class student{
public:
char * nume,* nr_de_identificare;
int
anul, cursul;
double media;
/******* Constructori *****/
student(); //Constructor implicit
student(char * , int , char * ,double ); //Constr. de init1
student(char * , char * ,double );//Constr. de init2
student(student& ); //Constructor
de copiere
~student(){}; // Destructor
/****** Metode *******/
void tipareste_student();
void bursa();
}; //sfirsitul declararii clasei
student::student(){
nume = "Nedefinit";
- 155 -
cursul = 0; media = 0;
nr_de_identificare = "Nedefinit";
cout<<endl<<"Constructor implicit "<<endl;
}
student::student(char * a, int c, char * n, double med){
nume=a; cursul=c;
nr_de_identificare=n;
media=med;
cout<<endl<<"Constructor de initializare1 "<<endl;
}
student::student(char * a1, char * n1, double med){
nume=a1; cursul=0;
nr_de_identificare=n1;
media=med;
cout<<endl<<"Constructor de initializare2 "<<endl;
}
student::student(student&C){
nume= C.nume; cursul= C.cursul;
nr_de_identificare= C.nr_de_identificare;
media= C.media;
cout<<endl<<"Constructor de copiere "<<endl;
}
void student::tipareste_student(){
cout<<"Metoda de afisare "<<endl;
cout<<"Nume: "<<nume<<endl<<"Cursul: "<<cursul<<endl;
cout<<"Numarul de identificare: "<<nr_de_identificare<<endl;
cout<<"Media: "<<media<<endl;
}
void student::bursa(){
cout<<"Metoda BURSA "<<endl;
if(media>7) cout<<"Studentul are bursa!"<<endl;
else if(media>5)cout<<"Studentul nu are bursa!"<<endl;
else cout<<"Studentul este restantier"<<endl;
}
void main(){
student st1("Lupei Rodica",2,"AR985I",9.81);
// apelarea constr. de init.1
st1.tipareste_student(); st1.bursa();
student st2("Popa Ion","RD726K",6.89);
// apelarea constr. de init.2
st2.tipareste_student(); st2.bursa();
student st3("Chistruga Alexandru",2,"AD564L",4.99);
st3.tipareste_student();
st3.bursa();
student st4(st1);
st4.tipareste_student();
student st; // apelarea constructorului implicit
st.tipareste_student();
}
- 156 -
- 157 -
7. Funcii prietene
Datele i metodele unei clase nu pot fi prelucrate n exteriorul clasei,
dac ele snt protejate cu modificatorii de protecie private sau protected.
Totui, uneori apare necesitatea prelucrrii acestor date n afara clasei lor.
Acest fapt este posibil prin intermediul aa numitor funcii prietene (friend
functions). Declararea unei funcii prietene f() clasei X se realizeaz astfel:
class X{
//
friend tip_returnat
f(parametru_de_tip_clas,lista_de_parametri);
};
tip_returnat f(parametru_de_tip_clas, lista_de_parametri){
// corpul functiei
}
- 158 -
}
void prieten(vector c){
c.citire(); c.afis();
}
main(){
randomize();
vector Q;
prieten(Q);
getch();
}
- 159 -
unde tip_data reprezint tipul definit, adic numele clasei, p este numele
pointerului de tip obiect, iar initializare (care poate s lipseasc) este o
expresie care depinde de tipul datei i permite iniializarea zonei de memorie
alocate. Dac alocarea nu este posibil, pointerul returnat este NULL.
Operatorul new poate produce apelul unui constructor.
Operatorul delete elibereaz o zon de memorie din heap alocat
anterior cu new. De regul, el se utilizeaz n interiorul destructorilor i poate fi
apelat n una din urmtoarele forme:
a) delete P se utilizeaz pentru eliberarea unei zone de memorie
ocupat de o singur dat (obiect), nu de un vector. Pointerul P trebuie s fie
un pointer la o zon de memorie alocat anterior printr-un operator new.
Folosirea operatorului delete cu un pointer care nu este valid este o operaie cu
rezultat nedefinit, cel mai adesea producnd erori de execuie;
b) delete [] P se folosete pentru eliberarea unei zone de memorie
ocupat de un vector de date. De exemplu, avnd alocarea int *V = new
int[10], instruciunea delete V va
elibera zona de memorie alocat
elementului V[0], iar instruciunea delete[] V va elibera spaiul de memorie
alocat ntregului tablou V.
Exemple de alocri i eliberri pentru obiecte ale claselor Complex i student
(declarate n exemplele anterioare):
Complex *pc0 = new Complex;
// apelarea constructorului
implicit
Complex *pc1 = new Complex(2);// apelarea constructorului cu un
parametru
Complex *pc2 = new Complex(3.5,2.9); //apelarea constr. cu 2
parametri
delete pc0; // apelarea destructorului
delete pc1;
delete pc2;
elev *p = new elev(Munteanu,Anatol,8.88);
p->afisare();
delete p;
Complex *pv1 = new Complex[4]; // crearea dynamica a vectorului
pv1
delete []pv1; // eliberarea memoriei rezervate vectorului pv1
- 160 -
Exemplu rezolvat
S crem un tablou de poiteri de tip student (care este o clas cu datele
membru: nume, prenume, anul, media i funcia membru afis(), utilizat pentru
afiarea acestor date).
Realizare:
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <iostream.h>
class student{
char *nume,*prenume;
int
anul;
double
media;
public:
student();
student(char *p1,char *p2);
student(char *p1,char *p2,int p3,double p4);
void afis();
~student();
};
student::student(){
char s[20];
cout<<"Constructor implicit"<<endl;
cout<<"Dati numele studentului";cin>>s;
nume=new char[strlen(s)+1];strcpy(nume,s);
cout<<"Dati prenumele studentului";cin>>s;
prenume=new char[strlen(s)+1];strcpy(prenume,s);
cout<<"Dati anul nasterii";cin>>anul;
cout<<"Dati media :";cin>>media;
}
student::student(char *p1,char*p2){
nume= p1;prenume= p2;
anul=0; media=0;
}
student::student(char *p1,char *p2,int p3,double p4){
nume= p1;prenume= p2;anul=p3;media=p4;
}
- 161 -
void student::afis(){
cout<<nume<<" "<<prenume<<" "<<anul<<" "<<media<<endl;
}
student::~student(){delete nume;delete prenume;}
void main(){
student *s[3];
int i;
s[0]=new student;
s[1]=new student("Moraru","Ion");
s[2]=new student("Ciobanu","Vasile",1990,8.75);
cout<<endl<<"Lista studentilor"<<endl<<endl;
for(i=0;i<3;i++) s[i]->afis();
getch();
for(i=0;i<3;i++) delete s[i];
}
9. Suprancrcarea operatorilor
9.1. Modaliti i forme de suprancrcare
n C++ se pot defini operaii cu obiectele claselor folosind simbolurile
operatorilor standard. n acest caz se spune c operatorii standard snt
suprancrcai.
O funcie care definete pentru o clas o operaie echivalent operaiei
efectuate de un operator asupra unui tip predefinit este numit funcie operator.
Majoritatea operatorilor limbajului C++ pot fi suprancrcai, cu excepia
operatorilor ., *, ::, ?:.
Procedeul de suprancrcare const n definirea unei funcii cu numele
operator S, unde operator este cuvnt-cheie, iar S simbolul unui operator
din C++.
Procesul de suprancrcare a unui operator poate fi realizat prin
intermediul:
a) unei funcii membru;
b) unei funcii prietene clasei pentru care urmeaz a fi suprancrcat
operatorul.
a) Forma general de suprancrcare a unui operator S prin intermediul unei
funcii membru:
- 162 -
class nume_clasa
{
// datele i metodele clasei
tip operator S(lista_de_parametri);
};// sfirsitul declaratiei clasei
tip nume_clasa::operator(lista_de_parametri){
// descrierea procesului de suprancrcare
}
unde S este operatorul suprancrcat, tip tipul rezultatului operaiei S,
lista_de_parametri reprezint operanzii care particip la operaia S.
iar
iar
Observaie
1. n cazul suprancrcrii prin funcii membru lista_de_parametri va
conine cu un parametru mai puin (din cauza c prin intermediul funciilor
membru este acces la obiectul curent).
2. Dac suprancrcarea este realizat printr-o funcie prieten, atunci primul
operant va reprezenta obiectului curent.
- 163 -
Exemple rezolvate
1. Suprancrcarea operatorului +
S crem un exemplu n care vom suprancrca operatorul + pentru
clasa complex. Deoarece adunarea numerelor complexe este comutativ, vom
examina cazurile:
1. complex + complex
2. double + complex
3. complex + double
n primul i al treilea caz suprancrcarea poate fi efectuat prin
intermediul funciilor membru, ns n cazul doi suprancrcarea este posibil
numai prin intermediul unei funciei prieten, deoarece primul parametru al unei
funcii membru operator este implicit de tipul clasei i nu poate fi de alt tip.
Rezolvare:
#include<iostream.h>
class complex{
public:
double x,y;//complex=x+yi
void citire();
void afisare();
complex operator +(complex);
friend complex operator +(double, complex);
complex operator+(double);
};
void complex::citire(){
cout<<partea reala;cin>>x;
cout<<partea imaginara;cin>>y;
}
void complex::afisare(){cout<<x<<+<<y<<i<<endl;}
- 164 -
2. Suprancrcarea operatorului =
n cazul n care operatorul de atribuire nu este suprancrcat explicit,
compilatorul genereaz unul implicit i copie valorile datelor membri ale
operandului drept direct n datele membri ale operandului stng.
Operatorul de atribuire implicit este nesatisfctor n situaiile n care
- 165 -
obiectele clasei au date membri de tip pointer, sau n situaiile n care memoria
este alocat n mod dinamic.
S crem dou exemple n care vom suprancrca explicit operatorul =
pentru clasa complex prin intermediul unei funcii membru i respectiv cu
ajutorul unei funcii friend.
Realizare:
a) Suprancrcarea operatorului = pentru clasa complex prin intermediul unei
funcii membru.
class complex{
public:
double x,y;
complex operator = (complex );
};
complex complex::operator = (complex z){
x=z.x; y=z.y; return *this;
//this este pointer ctre obiectul curent, a n main
}
void main(){
complex a, b;
a = b;
}
- 166 -
//descrierea suprancrcrii :
int operator@( nume_clasa ob1, nume_clasa ob2){
if(condiia de comparare) return 1;
else return 0;
}
- 167 -
S crem un exemplu n care vom suprancrca operatorii <<, >> pentru clasa
complex.
Realizare:
#include<iostream.h>
class complex {
public:
double x, y;
friend ostrem& operator << (ostrem& os, complex z);
friend istream& operator >>(istream& is,complex& z);
};
ostream& operator<<(ostream& os, complex z){
os <<z.x;
if(z.y==0) os<<endl;
if(z.y<0) os<<-<<z.y<<i<<endl;
if(z.y>0) os<<+<<z.y<<i<<endl;
return os;
}
istream& operator>>(istream& is, complex& z){
cout<<Dati partea reala ; is >> z.x;
cout<<Dati parteaimaginara; >> z.y;
return is;
}
- 168 -
main(){
complex x,y;
cout<<Introdu primul nr complex; cin>>x;
cout<<Introdu a-l doilea nr complex; cin>>y;
cout<<x<<y;
}
- 169 -
private
protected
public
private
protected
public
private
protected
public
public
public
public
protected
protected
protected
private
private
private
private
protected
public
private
protected
protected
private
private
private
nu exist
nu exist
exist
nu exist
nu exist
nu exist
nu exist
nu exist
nu exist
Exemplu rezolvat
- 170 -
char *nume;
double salariu;
public:
void set_ang(char *n, double sal);
void afis_ang();
};
void Angajat::set_ang(char *n, double sal){
int size = strlen(n); nume = new char[size+1];
strcpy(nume, n); salariu = sal;
}
void Angajat::afis_ang(){
cout << "Nume: " << nume<< " Salariu: " << salariu << endl ;
}
class Administrator : public Angajat {
int sectie;
public:
void set_admin(char *n, double sal, int sec);
void afis_admin();
};
void Administrator::set_admin(char *n,double sal, int sec){
int size = strlen(n); nume = new char[size+1];
strcpy(nume, n); salariu = sal; sectie=sec;
}
void Administrator::afis_admin(){
afis_ang();
cout << "Sectia : " << sectie << endl;
}
void main(){
Angajat a1;
cout<<"Datele despre Angajat ";
a1.set_ang("Manole", 2000);
a1.afis_ang();
Administrator m1;
m1.set_admin("Frunza", 3000, 1);
cout<<"Datele despre Administrator ";
m1.afis_admin();
}
- 171 -
- 172 -
public:
int j;
derivat(int x,int y){j=x;i=y;cout<<"construeste
derivat"<<endl;}
void arata(){cout<<i<<" "<<j<<endl;}
};
main(){
derivat ob(3,4);
ob.arata();
}
Exemplu rezolvat
n acest program se ilustreaz modul de utilizare a constructorului cu
parametri ntr-o relaie de motenire Baz Derivat.
#include<iostream.h>
class baza{
public:
int i;
baza(){};
baza(int x){i=x; cout<<"construeste baza"<<endl;}
};
class derivat:public baza {
public:
int j;
- 173 -
derivat(){};
derivat(int x,int y): baza(y){
j=x; cout<<"construeste derivat";
}
void arata(){cout<<i<<" "<<j<<endl;}
};
main(){
derivat ob(3,4);
ob.arata();
}
- 174 -
Realizare:
#include <string.h>
#include <iostream.h>
#include<conio.h>
class student{ // descriem clasa student
protected:
char *nume,*prenume;
int
anul;
double
media;
public:
student();
student(char *p1,char *p2,int p3,double p4);
void afis();
};
student::student(){ //definim constructorul clasei de baza
char s[20];
cout<<"Numele studentului";cin>>s;
nume=new char[strlen(s)+1];
strcpy(nume,s);
cout<<"Prenumele studentului"; cin>>s;
prenume=new char[strlen(s)+1];
strcpy(prenume,s);
cout<<"Anul nasterii"; cin>>anul;
cout<<"Media :"; cin>>media;
}
student::student(char *p1,char *p2,int p3,double p4){
nume= p1;
prenume=p2;
anul=p3;
media=p4;
}
void student::afis(){
cout<<nume<<" "<<prenume<<" "<<anul<<" "<<media<<endl;
}
class bugetar:public student{ //descriem clasa bugetar
public:
bugetar(){};
bugetar(char *p1,char *p2,int p3,double
p4):student(p1,p2,p3,p4){};
int bursa(){if(media>8) return 200;else return 0;}
void afis(){student::afis();cout<<"Bursa "<<bursa()<<endl; }
};
void main(){
student *s1,*s2;
- 175 -
int i;
bugetar *a,*b;
cout<<"lucru cu pointeri de tip student"<<endl;
s1=new student("Ciobanu","Vasile",1990,7.75);
s2=new bugetar("Ciubotaru","Vlad",1989,8.75);
cout<<endl<<"studentii din lista"<<endl<<endl;
s1->afis();
s2->afis();
cout<<endl<<"lucru cu pointeri de tip bugetar"<<endl;
b=new bugetar("Moraru","Ion",1989, 9.2);
b->student::afis();
b->afis();
delete s1;
delete s2;
delete b;
getch();
}
Observaii.
1. Dac o metod este declarat ca funcie virtual n clasa de baz, ea va
fi virtual pentru toate clasele derivate.
2. O metod virtual este declarat cu scopul de a o utiliza i n alte clase
(nu numai n clasa de baz).
3. Redefinirea unei funcii virtuale ntr-o clas derivat domin definiia
funciei n clasa de baz.
Exemple rezolvate
- 176 -
- 177 -
patrat(double a){l=a;}
void afisare(){cout<<"patrat l= "<<l<<endl;}
virtual double arie(){return l*l;}
};
class cub : public patrat{
public:
cub(double w):patrat(w){};
void afisare(){cout<<"cub l="<<l<<endl;}
double arie(){return patrat::arie()*l;}
};
void main(){
patrat *s[10];
s[0]=new patrat(5);
s[1]=new cub(12);
cout<<"metodele nevirtuale"<<endl;
s[0]->afisare();
s[1]->afisare();
cout<<"metodele virtuale"<<endl;
cout<<"patrat "<<s[0]->arie()<<endl;
cout<<"cub "<<s[1]->arie()<<endl;
delete s[0];
delete s[1];
}
La consol se va afia:
metodele nevirtuale
patrat l= 5
patrat l= 12
metodele virtuale
patrat 25
cub 1728
- 178 -
12.2. Polimorfism
n preliminariile acestui capitol am menionat c polimorfismul d
posibilitatea ca att clasa derivat, ct i clasa de baz s poat utiliza metode cu
acelai nume, dar cu diferite funcionaliti.
De cele mai dese ori polimorfismul se realizeaz prin intermediul
funciilor virtuale. Declarate n clasa de baz, se presupune c acestea vor fi
implementate n clasele derivate.
n cazul funciilor normale (pentru care snt cunoscute adresele de apel) se
spune c legarea dintre obiect i funcie este timpurie, n sensul c aceast legare are
loc n timpul compilrii programului. Apelurile soluionate n timpul compilrii au o
vitez ridicat.
Exemplu rezolvat
S crem un program n care vom defini clasa de baz triunghi
(corespunztoare triunghiului echilateral) i clasele derivate piramida i prisma
(corespunztoare piramidei triunghiulare regulate i prismei triunghiulare
regulate). Programul va citi datele despre n astfel de figuri i corpuri
geometrice, apoi va afia denumirile celor cu aria maxim, respectiv cu
volumul maximal. Numrul n de figuri/corpuri geometrice, de asemenea, se va
citi de la tastatur.
- 179 -
Realizare:
Metodele afis i volum snt metode abstracte, adic pentru clasa triunghi ele nu
efectueaz nimic, dar vom avea nevoie de aceste metode n clasele derivate.
#include<math.h>
#include<conio.h>
#include<stdlib.h>
#include<iostream.h>
class triunghi{
protected:
double lat; //
public:
virtual void citire();
virtual double arie();
virtual void afis(){};
virtual double volum(){return 0;}
};
void triunghi::citire(){
cout<<"Introdu lungimea laturii (bazei): ";cin>>lat;
}
double triunghi::arie(){return lat*lat*sqrt(3)/4;}
class piramida:public triunghi{
protected:
double a,h;
public:
void citire();
double arie();
double volum();
void afis();
};
void piramida ::citire() { // redefineste metoda parintelui
cout<<"Introdu masurile piramidei"<<endl;
triunghi::citire(); // apeleaza metoda parintelui
cout<<"Introdu lungimea apotemei :";cin>>a;
cout<<"Introdu inaltimea piramidei:";cin>>h;
}
double piramida ::arie(){
double s;
s=triunghi::arie(); // aria bazei
s=s+triunghi::lat*a/2*3;
return s;
}
double piramida ::volum(){return triunghi::arie()*h/3;}
void piramida ::afis(){
cout<<"Piramida Aria "<<arie()<<" Volumul ";
cout<<volum()<<endl;
}
- 180 -
- 181 -
Exemplu rezolvat
S crem un program n care vom implementa clasa cuplu, derivat a
claselor barbat i femeie.
Realizare:
#include <iostream.h>
#include <conio.h>
class barbat{
public:
char *prenume;
int anul;
barbat(){};
- 182 -
- 183 -
b.afisare();
}
{
:
:
:
- 184 -
A
B
C
D
{
:
:
:
public: int x; };
virtual public A { /* */ };
virtual public A { /* */ };
public B, public C { /*
*/ };
Exemplu rezolvat
Pornind de la clasa de baz punct vom construi clasele cerc i patrat,
care la rndul lor vor deriva clasa figura.
Realizare:
#include<iostream.h>
#include<math.h>
#include<conio.h>
#include<graphics.h>
class punct{
protected:
int x,y,cul;
public:
virtual void citire();
virtual void des();
};
class patrat:virtual public punct{
protected:
int l;
public:
void citire();
void des();
};
class cerc:virtual public punct{
protected:
int raza;
public:
void citire();
void des();
};
class figura:public patrat, public cerc {
public:
void citire();
void des();
- 185 -
};
void punct::citire(){
clrscr();
cout<<"introdu x:";cin>>x;
cout<<"introdu y:";cin>>y;
cout<<"introdu culoare:";cin>>cul;
}
void patrat::citire(){
punct::citire();
cout<<"introdu latura patrarului:";cin>>l;
}
void punct::des(){putpixel(x,y,cul);}
void patrat::des(){
setcolor(cul);
bar(x-int(l/2),y-int(l/2),x+int(l/2),y+int(l/2));
}
void cerc::citire(){
punct::citire();
cout<<"Introduceti raza cercului:"; cin>>raza;
}
void cerc::des(){
setcolor(cul);
circle(x,y,raza);
}
void figura::citire(){
punct::citire();
cout<<"Introduceti latura patratului:"; cin>>l;
cout<<"Introduceti raza cercului:";
cin>>raza;
}
void figura::des(){
if(l*l>M_PI*raza*raza)
{patrat::des(); cerc::des(); }
else{ cerc::des(); patrat::des();}
punct::des();
}
void main(){
punct *masiv[10];
int i,g,m,n; char c;
cout<<"Introdu numarul figurilor"; cin>>n;
for(i=0;i<n;i++){
cout<<"Tastati"<<endl<<"1-PUNCT"<<endl<<"2-PATRAT";
cout<<endl<<"3-CERC"<<endl<<"4-FIGURA"<<endl;
c=getch();
clrscr();
switch(c) {
case '1': masiv[i]=new punct;break;
case '2': masiv[i]=new patrat;break;
case '3': masiv[i]=new cerc;break;
case '4': masiv[i]=new figura; break;
}
- 186 -
masiv[i]->citire();
}
g=DETECT;
initgraph(&g,&m,"d:\\Tc\\bgi");
for(i=0;i<n;i++) {
cleardevice();
masiv[i]->des();
getch();
}
closegraph();
delete []masiv;
}
- 187 -
(lista parametric
- 188 -
#include<iostream.h>
template<class T>
void sort(T* vect, int n){
int i,j;
T x;
for(i=1; i<n; i++){
x = *(vect + i);
j = i - 1;
while((j >= 0) && (x < *(vect + j))){
*(vect + j + 1) = *(vect + j); j--;
}
*(vect + j + 1) = x; } }
main(){
int i;
double dv[] = {4.7, 0.66, 7.0, 1,8, 3.0, 12.9};
int iv[] = {10, 9, 5, 3, -2, 4};
char cv[] = {'f', '4', 'h', 'i', 'a', 'c'};
sort(dv,6);
sort(iv,6);
sort(cv,6);
cout<<"Tipul double"<<endl;
for (i=0; i<6; i++)
cout << dv[i] << " ";
cout<<endl<<"Tipul int"<<endl;
for (i=0; i<6; i++) cout << iv[i] << " ";
cout<<endl<<"Tipul char"<<endl;
for (i=0; i<6; i++) cout << cv[i] << " ";
}
- 189 -
individuale, diferite prin tipul sau tipurile de date asupra crore se opereaz.
Prefixul template <class T> specific declararea unui template cu un
argument T. Dup aceast introducere, T este folosit exact la fel ca orice tip de
date, n tot domeniul clasei template declarate.
Numele unei clase template urmat de numele tipurilor de date folosite
ca argumente, ncadrate ntre parantezele < i > este numele unei clase
(definite aa cum specific template-ul) i poate fi folosit la fel ca oricare alt
clas.
Utilizarea template-urilor implic generarea de ctre compilator a
fiecarei clase care corespunde tipului (sau tipurilor) de date folosit la declararea
unui obiect.
Exemplu rezolvat
S elaborm un program care va prelucra elementele unui vector de orice
tip ordinal.
#include<iostream.h>
template <class T> class vector{
public:
T *v,x;
int n;
vector(int c){n=c; v=new T[n];}
void citire();
void afisare();
void sortare();
~vector(){delete []v;}
};
template <class T> void vector<T>::citire(){
for(int i=0;i<n;i++) {
cout<<"Introdu elementul "<<i<<
;
cin>>v[i];
} }
template <class T> void vector<T>::afisare(){
for(int i=0;i<n;i++) cout<<v[i]<<" ";
cout<<endl;
}
template <class T> void vector<T>::sortare(){
int i,j;
for(i=1; i<n; i++) {
x = v[i]; j = i - 1;
while((j >= 0) && (x < v[j])) {
v[j+1] = v[j]; j--;
} v[j+1] = x;
}}
main(){
vector<int> v1(5);
- 190 -
vector<double> v2(5);
vector<char> v3(5);
cout<<" 5 valori int "<<endl;
v1.citire();
cout<<" 5 valori double "<<endl;
v2.citire();
cout<<" 5 valori char "<<endl;
v3.citire();
cout<<"valori citite"<<endl;
v1.afisare();
v2.afisare();
v3.afisare();
cout<<"vectorii sortati"<<endl;
v1.sortare();
v1.afisare();
v2.sortare();
v2.afisare();
v3.sortare();
v3.afisare();
}
- 191 -
Ierarhizarea abloanelor
Prin intermediul abloanelor clasele pot fi ierarhizate. Ierarhizarea se
poate efectua prin dou direcii:
Prin motenire. Atunci cnd o clas transmite parametri sau
funcionalitatea altei clase, care la rndul su, se consider clas de baz pentru
o alt ierarhie de motenire.
Prin agregare. Agregarea este relaia ntre dou obiecte n care unul
dintre obiecte aparine celuilalt obiect. Agregarea red aparena unui obiect la
un alt obiect. Semantic, agregarea indic o relaie de tip "part of" ("parte
din").
Motenirea abloanelor
Clasele template ca i clasele obinuite susin mecanismul de motenire.
Toate principiile de baz ale motenire rmn neschimbate. Astfel se ofer
posibilitatea de a construi modele ierarhice de clase. Fie dat ierarhia:
Problema 3
Se consider drept baz clasa dreptunghi, iar n calitate de derivat
clasa prism. Pentru aceast ierarhie va fi realizat polimorfismul pentru
metodele citire, afisare, suprafata i volum. Se va descrie i constructorii
ambelor clase.
- 192 -
#include<iostream.h>
template <class T> class drept {
public:
T a,b;
drept(){};
drept(T,T);
virtual void citire();
virtual void afisare();
virtual T suprafata();
virtual T volum(){return 0;}//metod virtuala pura
};
template <class T> drept<T>::drept(T x, T y){a=x;b=y;}
template <class T> void drept<T>::citire(){
cout<<"a=";cin>>a;
cout<<"b=";cin>>b;
}
template <class T> void drept<T>::afisare(){
cout<<"Dreptunghi lungimile laturilor: "<<a<<" "<<b<<endl;
cout<<"Suprafata: "<<suprafata()<<endl;
}
template <class T> T drept<T>::suprafata(){return a*b;}
template <class T> class prisma : public drept< T> {
public:
T h;
prisma(){};
prisma(T,T,T);
void citire();
void afisare();
T suprafata();
T volum();
};
template <class T> prisma<T>::
prisma(T x,T y,T z):drept<T>(x,y){h=z;}
template <class T> void prisma<T>::citire(){
drept<T>::citire();
cout<<"h=";cin>>h;
}
template <class T> void prisma<T>::afisare(){
cout<<"Prisma lungimile laturilor bazei: ";
cout<<a<<" "<<b<<"Inaltimea: "<<h<<endl;
cout<<"Suprafata: "<<suprafata()<<" Volumul: "<<volum()<<endl;
}
template <class T> T prisma<T>::suprafata(){
return 2*(a*b+a*h+b*h);}
template <class T> T prisma<T>::volum(){
return drept<T>::suprafata()*h;}
int main(){
int i; double st,vt;
drept<int> *p[4];
p[0]=new drept<int>(2,3);
- 193 -
p[1]=new prisma<int>(4,2,7);
p[2]=new drept<int>; p[2]->citire();
p[3]=new prisma<int>;p[3]->citire();
cout<<"Datele introduse de tipul int"<<endl;
for(i=0;i<4;i++) p[i]->afisare();
drept<double> *t[4];
t[0]=new drept<double>(2.5,3);
t[1]=new prisma<double>(4.3,2,7.4);
t[2]=new drept<double>; t[2]->citire();
t[3]=new prisma<double>;t[3]->citire();
cout<<"Datele introduse de tipul double"<<endl;
for(i=0;i<4;i++) t[i]->afisare();
prisma<double> b[3];
cout<<"Dati datele a 3 prisme"<<endl;
for(i=0;i<3;i++)
b[i].citire();
vt=st=0.0;
cout<<"Datele introduse"<<endl;
for(i=0;i<3;i++){ b[i].afisare();
vt+=b[i].volum();
st+=b[i].suprafata();
}
cout<<"Volumul total:="<<vt<<endl;
cout<<"Suprafata totala:="<<st<<endl;
return 0;
}
- 194 -
- 195 -
cout<<"2-Inserare"<<endl;
cout<<"3-Exclude"<<endl;
cout<<"0-iesire"<<endl;
c=getch();clrscr();
switch(c){
case '1':a.parcurge();getch();break;
case '2':a.inserare();break;
case '3':a.exclude();break;
}clrscr();
}while(c!='0');
}
int main(){
clrscr();
cout<<"Stiva de numere intregi"<<endl;
stiva<int> sn;
meniu(sn);
cout<<"Stiva de caractere"<<endl;
stiva<char> sc;
meniu(sc);
return 0;
}
- 196 -
Cuprins
Prefa..................................................................................................
4
12
3. Aplicaii de consol.......................................................................
15
4. Generaliti....................................................................................
18
20
27
8. Clasa AnsiString............................................................................ 29
9. Clasa TLabel.................................................................................. 31
10. Ferestre pentru afiarea mesajelor...............................................
39
41
42
47
51
55
64
75
82
- 197 -
90
97
104
110
123
4. Interogri.......................................................................................
130
5. Rapoarte......................................................................................... 134
6. Tehnologia ADO...........................................................................
138
148
2. Clase..............................................................................................
149
152
153
6. Destructor......................................................................................
155
7. Funcii prietene..............................................................................
158
159
9. Suprancrcarea operatorilor..........................................................
10. Motenirea obiectelor..................................................................
162
169
172
176
- 198 -
187