<<Pagina Materiale

 
 
De la C la C++ 


Perspective istorice ale limbajului C++

Notiunea de obiect apare in multe contexte: OOPLs (Object-Oriented Programming Languages),  OODBs (Object-Oriented Databases), OOA (object-oriented analysis), sau OOD (object-oriented design). 

In modulele de C++ vom explora intr-o maniera practica programarea orientata pe obiecte.

In deceniul 9, s-a inregistrat o adevarata explozie a tehnologiei OO odata cu aparitia limbajului Smalltalk. Programarea OO - Object-Oriented Programming (OOP) - a inceput sa o inlocuiasca pe cea traditionala, structurata. 

Paradigma OO nu este insa atat de noua, multe idei din OOP fiind luate de la Simula-67, limbaj dezvoltat in jurul anului 1967.

Au aparut multe limbaje OO: Object-Pascal, Modula-2, Mesa, Cedar, Neon, Objective-C, Common List Object System (CLOS), sau C++. 

Exista limbaje concepute strict pe baza conceptelor programarii orientate pe obiecte (POO), de exemplu Simula sau Smalltalk. O alta abordare este de a adauga unor limbaje cu o popularitate bine stabilita, de exemplu Pascal si C, elementele tehnicii POO - rezultand Object-Pascal, respectiv C++.

In 1980, la Laboratoarele Bell, Bjarne Stroustrup a dezvoltat C cu clase, numit in 1983 C++. Creatorul lui afima: "caracteristicile de orientare pe obiecte din C++ permit programelor sa fie structurate pentru a fi clare, extensibile si usor de intretinut, fara pierderea eficientei".

De la aparitie, C++ a trecut prin trei mari revizuiri: in 1985, 1989, iar a treia cand a inceput lucrul la standardul ANSI pentru C++; prima versiune a standardului a fost creata in ianuarie 1994, cea considerata finala fiind din 1998.

C++ combina avantajele oferite de limbajul C( eficienta, flexibilitate si popularitate) cu avantajele oferite de tehnica POO. Desi adopta principiile POO, C++ nu impune aplicarea lor stricta ( se pot scrie programe fara elemente POO ). Conceptul fundamental în C++ este clasa.

Clasele:

  • sunt tipuri definite de utilizator
  • asigura încapsularea datelor
  • garanteaza initializarea datelor
  • permite gestiunea memoriei controlata de utilizator
  • ofera mecanisme pentru supraîncarcarea operatorilor.
C++ contine de asemenea îmbunatatiri ale limbajului C care nu sunt direct legate de POO, cum ar fi: tipul referinta, substitutia “in-line” a functiilor, nume de functii supraîncarcate, operatori pentru gestionarea memoriei libere.
Sus
Imbunatatiri ale limbajului C introduse de C++

Fisierele sursa C++ vor avea extensia .cpp.

Comentariile sunt considerate textul pana la sfarsitul liniei care urmeaza perechii //.

Intr-o instructiune bloc, inclusiv corp de functie, declaratiile de variabile nu trebuie neaparat sa preceada prelucrarile, ci pot fi facute intercalat.

Exemplu:

{
int i=1;
i++;
char c; //declaratie e variabila ce urmeaza unei prelucrari
c='a'+i;
}

Daca o functie nu are parametri, la definirea ei nu trebuie sa apara void intre paranteze:

void main(){
...
}

1.Transmiterea parametrilor

În C++ exista doua posibilitati de transmitere a parametrilor actuali catre o functie:

  • mecanismul de transmitere prin valoare
  • mecanismul de transmitere prin referinta
Primul constituie modul standard de transmitere a parametrilor în C.

Prin folosirea parametrilor formali referinta se permite realizarea transferului prin referinta ( transmiterea adresei ) de o maniera similara celei din Pascal ( parametrii VAR ). Se elimina astfel necesitatea recurgerii la artificiul din C, adica utilizarea parametrilor formali pointeri, în cazul în care modificarile facute în interiorul functiei asupra parametrilor trebuie sa ramâna si dupa revenirea din procedura.

Exemplu:

    void interschimba_C(int *pa, int *pb) { //varianta pentru C
    int  aux=*pa; *pa=*pb; *pb=aux;
    }
    void interschimba_Cpp(int &a, int &b) {
    int  aux=a; a=b; b=aux;
    }
    //apel
    int a=9,b=5;
    interschimba_C(&a,&b);
    interschimba_Cpp(a,b);
Transferul prin referinta este util si atunci când parametrul are dimensiune mare (struct, class) si crearea în stiva a unei copii a valorii ar reduce viteza de executie si ar încarca stiva, mai performanta fiind transmiterea prin referinta; problema incarcarii stivei trebuie analizata mai ales in cazul programelor recursive..

2.Parametrii cu valori implicite

C++ ofera posibilitatea declararii functiilor cu valori implicite ale parametrilor. La apelarea unei astfel de functii se poate omite specificarea parametrilor efectivi pentru acei parametri formali care au declarate valori implicite si se transfera automat valorile respective. Se pot specifica mai multe argumente cu valori implicite pentru o functie. Este obligatoriu ca numai ultimele argumente sa aiba astfel de valori si nu este permisa alternarea argumentelor cu si fara valori implicite.

Exemplu:

    void fct(int, int=10);
    void tipareste(int i){
      printf("%d ",i);
    }

    void fct(int p1, int p2){
      tipareste(p1); tipareste(p2);
    }

    void main(){
      fct(1,2);
      fct(3); //implicit al doilea parametru actual este 10
    }

Rezultatul rularii acestui program va fi tiparirea numerelor:
1 2 3 10

3.Functii inline

O tehnica utila pentru a mari performanta programelor ce folosesc multe functii de foarte mici dimensiuni, pentru care regia de apel este semnificativa în raport cu timpul de executie al functiei propriu-zise, este folosirea functiilor inline - In C directiva #define este utilizata pentru aceasta . Functiile declarate ca inline vor fi expandate in-line la compilare, compilatorul generând codul corespunzator functiei în pozitia apelului, în loc de a genera secventa de apel. Pentru a indica faptul ca o functie este de acest tip, se precede declaratia sau definitia ei cu cuvântul cheie inline.

 Exemplu:

    #define max (x, y) ((x)>(y)?(x):(y)) //varianta C

    inline int max (int x, int y){ //varianta C++
        return (x > y ? x : y);
    }

4.Supradefinirea (supraîncarcarea) functiilor

Supradefinirea reprezinta posibilitatea de a atribui unui simbol mai multe semnificatii, care pot fi deduse în functie de context. Limbajul C++ permite supraîncarcarea ( overloading ) functiilor, adica existenta mai multor functii cu acelasi nume. Când compilatorul întâlneste un apel la o functie supraîncarcata, va determina care functie va fi apelata prin examinarea numarului si tipului argumentelor. Nu se verifica si tipul valorii returnate, deci doua functii supraîncarcate nu pot diferi doar prin valoarea returnata.

Exemplu:

    void fct(int a) {
       cout << "functia 1" << a;
    }

    void fct(char *a) {
       cout << "functia 2" << a;
    }

In particular, majoritatea operatorilor C++ pot fi priviti ca nume de functii si deci pot fi supraîncarcati. Antetul unei asemenea functii contine cuvântul cheie operator în fata simbolului operatorului.

5. Alocarea dinamica a memoriei folosind operatorii new si delete

Operatorii new si delete sunt similari functiilor din grupul malloc() si free(), dar constituie o metoda noua, superioara acestora si adaptata programarii orientate pe obiecte.

Operatorul new poate fi folosit în urmatoarele situatii:

Exemplu:

    int * ip1, *ip2, *ip3;
    ip1=new int;     // variabila întreaga neinitializata
    ip2=new int(2);   // variabila întreaga initializata cu 2
    ip3=new int[100]; // tablou de 100 de întregi
Operatorul new poate fi folosit si la alocarea dinamica a obiectelor, în cazul acesta permitând apelarea constructorului clasei.

Operatorul delete este complementarul lui new si înlocuieste functia free() de dezalocare a memoriei dinamice alocate. Daca exista un destructor pentru obiectul care se dezaloca, acest destructor va fi apelat automat de catre delete.

6. Operatorul de rezolutie

In C++ este definit un operator de rezolutie ( :: ), care permite accesul la un identificator cu domeniu fisier, dintr-un bloc în care acesta nu este vizibil, datorita unei alte declaratii. Principala aplicatie a operatorului este legata de clase si obiecte si va fi prezentata mai târziu.

Exemplu:

    int n=1;
    void main() {
        int n=2;
        afiseaza(n); // afiseaza 2, valoarea variabilei locale n
        afiseaza(::n); // afiseaza 1,valoarea variabilei globale n
    }
Sus
Exercitii

1.Ce se tipareste pe ecran la executia secventei:

void prel(int & a, int * b, int c ){
  ++a;++(*b);++c;
}
void main(){
  int x,y,z;
  x=y=z=5;
  prel(x,&y,z);
  printf("%d %d %d\n",x,y,z);
  getchar(); 
}

2.Ce se tipareste pe ecran la executia secventei:

void salut(char* s="Buna dimineata!"){
  puts(s);
}
void main(){ 
  salut();
  salut("La revedere!"); 
  getchar();


 Apare eroare in compilare


 Buna dimineata!
 La revedere!


 rand gol
 La revedere!

3.Rulati programul de mai jos si identificati aspectele teoretice prezentate anterior:
 

#include <stdio.h>
#include <string.h>

void tip(int i, char *s){
  printf("De %d %s\n",i,s); 
}
void tip(char *s){
  puts(s); 
}

int *px=new int(12);

void main(){ 
  char *px=new char[12]; 
  strcpy(px,"Invat C++!");
  tip(px);
  tip(*(::px),"ore");
  delete(px);
  delete(::px);
  getchar();

Sus
<<Pagina Materiale


Copyright © 2001-2002. Carmen Holotescu
All rights reserved. Published by Timsoft