Índex
Miguel A. Almarza
Departament d'Informàtica
IES Mare de Deu de la Merce

CplusPlus.zip      

 
Capítol 1

Introducció a la programació en C++.

  1. Introducció
  2. El primer programa en C++
  3. Introducció als conceptes de la programació dirigida a objectes.
  4. Classes i objectes.
    1. la classe punt.
    2. La classe PilaCaracters.
  5. Funcions constructores o contructors. Destructors.
    1. Contructors per a la classe PilaCaracters.
    2. Contructors per a la classe Punt.
    3. Destructors.
    4. La classe String. Constructors i destructors amb assignació dinàmica de memòria.
  6. Introducció a l'herència.
  7. Exercicis.


1.1. Introducció

Aquestes pàgines web pretenen ser uns apunts del llenguatge C++ dirigides a alumnes que ja han fet un curs de programació en el llenguatge C.

Així donarem moltes coses comunes als dos llenguatges com assumides per l'alumne i ressaltarem algunes diferències que apareixen entre aquests dos llenguatges.

La diferència més notable entre el C i el C++ és el fet que C++ és un llenguatge de programació dirigit a objectes i C no ho és. Així veurem al llarg d'aquests apunts que la creació d'un programa en C++ es basa fonamentalment en l'estudi dels objectes i llibreries d'objectes adients i no en la creació de funcions i llibreries de funcions com en el llenguatge C.

Les pràctiques del curs de C++ es faran amb la versió 3 de Turbo C++, i els programes d'exemple escrits en aquests apunts també han estat escrits provats amb aquest compilador. 

1.2. Els dos primers programes en C++.

Aquest dos primers programes ens indiquen com fer la entrada i sortida elemental de dades, entrada del dispositiu estàndard de d'entrada (teclat en aquest cas) i sortida també cap al dispositiu de sortida estàndard (pantalla en aquest cas).

Ens fixem que la llibreria que conté les classes i objectes que manipulen els fluxos de entrada i sortida d'informació és la llibreria iostream.h. Dins els seus objectes hi ha l'objecte cout que correspon a un flux de sortida i l'objecte cin que correspon a un flux d'entrada.

També apareixen els operadors d'entrada d'informació >>, i de sortida dinformació <<.
 
Operador d'entrada >> S'encarrega de rebre la informació del flux d'entrada (cin) i posar-la en el lloc adient, com la zona de dades de memòria d'una variable.
Operador de sortida << Agafa les dades que té escrites a la dreta i les deposita en el flux de sortida (cout);

En darrer lloc comentar que a diferència de les funcions printf i scanf no hem d'indicar el tipus de variable que volem imprimir o llegir.

Més endavant farem tot un capítol dedicat a la entrada i sortida en C++.
 
El primer programa C++
#include <iostream.h>

main()
{
          int Num;
          Num = 5;
          cout << "El valor de Num és " << Num << "i el seu quadrat és " << Num * Num << "\n";
          return 0;
}
El segon programa C++
#include <iostream.h>

main()
{
          int Num;
          cout << "Esriu un número ";
          cin >> Num;
          cout << "El número que has escrit és el " << Num <<"\n";
}

1.3. Introducció als conceptes de la programació dirigida a objectes.

Quan parlem de programació dirigida a objectes parlem de classes d'objectes i elements d'aquestes classes. Es tracta d'identificar ents (classes i objectes) i missatges entre aquests objectes que configurin el programa que voldrem fer.

Un objecte està format per un conjunt de dades (propietats de l'objecte) i un conjunt de funcions membre (mètodes d'aquest objecte) que conformen una unitat. Podem dir que un objecte és un ent que té unes propietats i sap fer coses.

En el paradigma de la programació dirigida a objectes tenim els tres conceptes següents: Encapsulació, polimorfisme i herència.

Encapsulació: per aquest concepte els llenguatges de programació dirigida a objectes fan que les propietats i els mètodes d'un objecte no siguin accessibles per altres objectes, o deixen a criteri del programador la forma en que altres objectes poden accedir-hi. Podem fer que un objecte sigui una capsa negra que oculta les seves dades i els seus mètodes i d'aquesta manera les propietats i mètodes d'un objecte són accesibles només pel mateix objecte.

Polimorfisme: Aquest concepte fa que podrem declarar i definir funcions (mètodes) que amb el mateix identificatiu actuïn sobre diferents tipus de dades o podrem declarar i definir objectes del mateix tipus però que tindran diferents tipus de dades. L'exemple clàssic és l'objecte pila. Una pila és un objecte que conté dades de tipus enter o de tipus float, etc. En la programació estructurada per a cada tipus de dades hem d'escriure les funcions d'apilar o extreure elements de la pila (push i pop) i si hem de fer ús de diferents tipus de piles en el mateix programa haurem de donar diferents noms a les funcions push i pop per a cada tipus de dades. Mitjançant el polimorfisme podrem fer diferents funcions amb el mateix nom.

Herència: Examinen l'objecte moble. És un objecte que té les propietats (dades) pes i material en que està fet. Una seient és un moble que té les propietats anteriors i també la propietat tipus de seient. És a dir, l'objecte seient hereta les propietats de l'objecte moble i té propietats pròpies que no tenen els altres mobles. Ens adonem que les propietats pes i material són propietats comuns a tots els mobles, per tant són propietats més genèriques. Un seient té una propietat molt més específica que és la de tipus de seient. Així tenim que quan parlem d'herència estem parlant de la creació d'un arbre d'objectes de manera que els objectes més específics hereten les propietats i mètodes dels objectes més genèrics.

Ja que la programació dirigida a objectes té com a punt central l'estudi i creació d'objectes per crear programes hem de pensar en aquests tres conceptes, encapsulació, polimorfisme i herència per crear un conjunt d'objectes flexible, reutilitzable, i fàcil d'entendre. 

1.4. Classes i objectes.

Quan identifiquem un objecte pensem les propietats i els mètodes que ha de tenir i tot aquest conjunt és el que en C++ anomenem com a classe. Una vegada tenim escrit el codi corresponent a una classe podem fer-ne ús per crear instàncies de la classe, és a dir, objectes propiament dits.

Exemple de classe: tenim la classe Punt que té com a propietats les variables x, y i Caracter i els mètodes PosaCoordenades, PosaCaracter i Dibuixa.

Exemple d'objectes: Dins la funció main() tenim les declaracions Punt A i Punt B. Aquestes declaracions creen instàncies de la classe Punt. Tenim els dos objectes punt A i B. En el moment de fer la declaració d'un objecte de la classe punt es fa la reserva de memòria adient per emmagatzemar les dades corresponents. Així tindrem que cadascun dels punts A i B tindrà una zona de memòria pròpia per emmagatzemar les seves dades. És un mecanisme de creació d'objectes similar al de creació de variables o estructures.
 
Primer programa amb una classe. La classe Punt.
#include <iostream.h>
#include <conio.h>
Llibreries utilitzades.
class Punt
{
    int x;
    int y;
    char Caracter;

 public:
    void PosaCaracter(char c);
    void PosaCoordenades(int n1, int n2);
    void Dibuixat();
};
Aquesta és la declaració de la classe Punt. 

Veiem que existeixen dues seccions de codi diferents. Les propietats o dades estan a la secció privada de la classe i els mètodes els hem posat a la secció pública. 

Si no s'indica la secció on es posa una propietat o un mètode el compilador considera que són privats.

Això vol dir que en qualsevol part del codi del nostre programa podrem accedir a les funcions escrites en la part pública. 

Les dades es troben a la part privada i per tant només poden accedir a aquestes dades les funcions de la classe Punt.

void Punt::PosaCoordenades(int n1, int n2)
{
    x = n1;
    y = n2;
}


void Punt::PosaCaracter(char c)
{
    Caracter = c;
}

void Punt::Dibuixat()
{
    gotoxy(x,y);
    cout << Caracter;
}
Fins aquest moment hem declarat la existència d'una classe Punt. Ara hem de definir les funcions que es troben declarades dins la classe. La notació per tal d'escriure un mètode d'una classe és:

Tipus NomClasse::NomMètode(Llista de paràmetres)

Quan els mètodes s'escriuen fora de la declaració de la classe l'indiquem al compilador el mètode i la classe mitjançant l'operador d'àmbit ::

main()
{
    Punt A;
    A.PosaCoordenades(10,10);
    A.PosaCaracter('O');
    A.Dibuixat();

    Punt B;
    B.PosaCoordenades(15,10);
    B.PosaCaracter('G');
    B.Dibuixat();
}
Aquesta funció main és la funció d'arrancada d'un programa C++ igual que en el llenguatge C.

Dins la funció main es fa ús de la nova classe d'objectes Punt declarada abans. Mitjançant la declaració Punt A;, tenim l'objecte A de tipus Punt. Per donar valor a les propietats del punt A fem ús dels mètodes A.PosaCaracter('O') i A.PosaCoordenades(10,10). Podem fer ús d'aquesta notació pel fet que aquests mètodes són públics.

Important: No podem fer ús de la notació A.x=10; ja que hem declarat les propietat x com a privada. Si que haguéssim pogut fer-ne ús d'aquesta notació si haguéssim declarat la propietat x dins la secció pública.

Important: Els objectes d'aquesta classe tenen ocultes les seves propietats, es a dir, que no podem accedir a les seves dades des de la funció main o qualsevol altre lloc del programa. Per tal de corregir aquest problema hem de crear els mètodes per extreure informació dels objectes. Aquests mètodes han d'escriure's a la secció pública de la classe afegint el següent codi:
Completar la classe Punt.
int TornaX();
int TornaY();
char TornaCaracter();
Afegim les declaracions a la secció pública de la declaració de la classe.
int Punt::TornaX()
{
    return x;
}

int Punt::TornaY()
{
    return y;
}


char Punt::TornaCaracter()
{
    return Caracter;
}
Afegim el codi corresponent a les funcions en el lloc on hem definit les funcions.
cout << A.TornaX();
cout << A.TornaY();
cout << A.TornaCaracter();
Ara podem fer ús a la funció main dels nous mètodes per tal d'accedir les dades contingudes a les propietats de l'objecte A.

La classe PilaCaracters

Un exemple clàssic de la programació dirigida a objectes són les piles i les altres estructures d'informació. En aquests apunts seguirem la construcció de les piles millorant la seva programació a mesura que avancem en els conceptes de programació dirigida a objectes.

L'exemple que posem a continuació és una classe pila de caràcters que emmagatzema les seves dades en un vector de 10 caràcters. Ara hem de veure una classe pila com una classe en la que els seus objectes saben inicialitzar la pila, inserir un element i extreure un element.
 
La classe PilaCaracters
#include <iostream.h>
#define MIDA 10
Llibreria i constant MIDA per declarar després el vector del la pila.
class PilaCaracters
{
    char Pila[MIDA];
    int Cim;
 public:
    void InicialitzaPila();
    void InsereixElement(char Element);
    char ExtreuElement();
};
Les propietats dels elements de la classe PilaCaracters són el vector Pila i un punter Cim que ens indica la posició següent a la darrera ocupada en el vector pila.

Els mètodes són els que estan declarats a la secció pública de la classe i són els mètodes clàssics d'inicialitzar, inserir i extreure elements. Ja que els declarem dins la secció pública podrem accedir a través d'ells a les dades de les propietats, als valors del vector pila.

void PilaCaracters::InicialitzaPila()
{
    Cim=0;
}

void PilaCaracters::InsereixElement(char Element)
{
    if (Cim < MIDA)
    {
        Pila[Cim]=Element;
        Cim++;
    }
    else cout << "La pila està plena\n";
}

char PilaCaracters::ExtreuElement()
{
    if (Cim > 0)
    {
        Cim --;
        return Pila[Cim];
    }
    else
    {
        cout << "La pila està buida\n";
        return 0;
    }
}
Zona de definició dels mètodes:

El mètode InicialitzaPila fa que el punter Cim tingui el valor 0.

El mètode InsereixElement comprova si la pila està plena (Cim < MIDA) i cas que hagi espai al vector insereix l'element que rep.

El mètode ExtreuElement torna l'element que està més amunt de la pila i decrementa el punter Cim. Si la pila està buida torna un null.

main()

{
    int i;

    PilaCaracters Pila1;
    Pila1.InicialitzaPila();
    Pila1.InsereixElement('A');
    Pila1.InsereixElement('B');
    Pila1.InsereixElement('C');

    PilaCaracters Pila2;
    Pila2.InicialitzaPila();
    Pila2.InsereixElement('O');
    Pila2.InsereixElement('P');
    Pila2.InsereixElement('Q');

    cout << "Pila 1:\n";
    for(i=0; i<3; i++)
    {
        cout << "Element " << 3-i << ": ";
        cout << Pila1.ExtreuElement() <<"\n";
    }
        cout << "Pila 2:\n";
    for(i=0; i<3; i++)
    {
        cout << "Element " << 3-i << ": ";
        cout << Pila2.ExtreuElement() <<"\n";
    }
}
Ara fem ús de la classe PilaCaracters per declarar dos objectes d'aquest tipus, Pila1 i Pila2.

Veiem que com qualsevol funció membre d'un objecte podem fer ús de les funcions InicialitzaPila, InsereixElement i ExtreuElement des de els dos objectes.

1.5. Funcions constructores o contructors. Destructors.

Quan fem programes en llenguatges de programació estructurada sabem que hem d'inicialitzar les variables si volem tenir èxit en la programació.

La programació dirigida a objectes té implementat el mecanisme de les funcions constructores. Aquestes són funcions que s'executen en el moment de declarar un objecte i que es dediquen a fer la inicialització de les propietats de l'objecte declarat.

Aquestes funcions han de rebre el mateix nom que la classe i no poden tornar cap dada. Poden rebre paràmetres i poden escriure's diferents funcions constructores sempre que tinguin diferent número de paràmetres.

La funció constructora s'executa automàticament en el moment de declarar un objecte i no ha de cridar-se explícitament dins el nostre codi.

Veiem l'exemple de funció constructora a la classe PilaCaracters.
 
La classe PilaCaracters: Constructor.
class PilaCaracters
{
    char Pila[MIDA];
    int Cim;
 public:
    PilaCaracters();
    void InsereixElement(char Element);
    char ExtreuElement();
};

PilaCaracters::PilaCaracters()
{
     Cim=0;
}

main()
{
    PilaCaracters MiPila;
    char Caracter;
    for(Caracter='A';Caracter<'M';Caracter++)
        MiPila.InsereixElement(Caracter);
}
Veiem que a aparegut la funció constructora PilaCaracter() que substitueix a la funció void InicialitzaPila()

També ens adonem que les instruccions d'inicialització són les mateixes a les dues funcions.

A la funció main() veiem la instrucció de declaració de la pila MiPila

PilaCaracters MiPila;

En el moment d'executar-se aquesta instrucció de declaració també s'executa la funció constructora i inicialitza la propietat Cim a 0.

No hem d'escriure una funció explícita per inicialitzar les dades ja que el mecanisme per a aquesta tasca és el de les funcions constructores.

Veiem ara els constructors per a la classe Punt.
 
La classe Punt: Constructors.
class Punt
{
    int x;
    int y;
    char Caracter;

 public:
    Punt();
    Punt(int n1,int n2);
    Punt(int n1,int n2,char Car);

    void PosaCaracter(char c);
    void PosaCoordenades(int n1, int n2);
    void Dibuixat();
    int TornaX();
    int TornaY();
    char TornaCaracter();
    void ImprimeixDades();
};

Punt::Punt()
{
    x=y=0;
    Caracter = ' ';
}


Punt::Punt(int n1,int n2)
{
    x=n1;
    y=n2;
    Caracter = ' ';
}

Punt::Punt(int n1,int n2,char Car)
{
    x=n1;
    y=n2;
    Caracter = Car;
}

void Punt::ImprimeixDades()
{
    cout << "x = " << x;
    cout << ", y = " << y;
    cout << ", Caracter = " << Caracter;
        cout  << "\n";
}

main()
{
    Punt A;
    Punt B(5,4);
    Punt C(3,10,'X');

    A.ImprimeixDades();
    B.ImprimeixDades();
    C.ImprimeixDades();
}
Tenim tres constructors declarats a la classe Punt:
 
Punt();
Punt(int n1,int n2);
Punt(int n1,int n2,char Car);

Aquest tres constructors es corresponen amb les declaracions dels tres punts A, B i C que es troben a la funció main:
 

Punt A;
Punt B(5,4);
Punt C(3,10,'X');

Ens fixem que tenim tres constructors diferents amb el mateix nom peró amb diferents número de paràmetres.
 
Constructor Descripció
Punt();

Declaració:

Punt A;

Aquesta funció no ha de rebre paràmetres i inicialitza el punt a coordenades (0,0) i com a caràcter posa l'espai en blanc.
Punt(int n1,int n2);

Declaració:

Punt B(5,4);

Aquesta funció rep dos paràmetres que corresponen a les coordenades del punt. Posa l'espai en blanc com a caràcter.
Punt(int n1,int n2,char Car);

Declaració:

Punt C(3,10,'X');

En darrer lloc, aquest constructor rep les coordenades del punt i el caràcter que a de posar en les propietats de l'objecte declarat.

Nota: Hem afegit el nou mètode ImprimeixDades a aquesta classe Punt. És un mètode auxiliar que permet al programador veure per pantalla les dades de les propietats de l'objecte punt. És convenient fer aquest mètode a totes les classes que programem.

Així el resultat per pantalla quan executem aquest programa és:

Destructors

Parlem una mica de l'àmbit d'existència dels objectes declarats en un programa. Els objectes tenen els mateixos àmbits de vida que les variables o estructures estudiades fins ara.

Es a dir, que si declarem un objecte com a global aquest objecte existeix mentre que el programa està executant-se.

Si declarem un objecte com a objecte local dins una funció aquest objecte tindrà existència mentre la funció està executant-se.

Quan una variable o estructura surt de l'àmbit de la seva existència la memòria que ocupen les seves dades es lliura i queda a disposició del programa per a que pugui fer-ne ús, d'aquesta memòria, per a altres variables. Quan és el programador el que fa una reserva de memòria dinàmica, mitjançant instruccions de tipus alloc o new, és el programador el que ha de tenir cura de lliurar aquesta memòria quan el programa surt de l'àmbit d'existència d'aquestes variables.

Els destructors constitueixen el mecanisme implementat en C++ que ens ajudarà a lliurar la memòria ocupada pels objectes.

Els destructors són funcions membre d'una classe en els que podem escriure entre d'altres, les instruccions per lliurar la memòria que ocupen les dades d'aquest objecte. Els mètodes destructors s'executen automàticament quan es surt de l'àmbit d'existència d'una variable sense haver de cridar-los explícitament dins el nostre codi.

Hem de dir que no és obligatori escriure aquest mètode ja que el mecanisme de destrucció d'un objecte és el mateix que el de qualsevol altra variable. És clar que si que és obligatori quan fem ús de la reserva dinàmica de memòria.
 
La classe Punt: Destructor.
class Punt
{
    int x;
    int y;
    char Caracter;

 public:
    Punt();
    Punt(int n1,int n2);
    Punt(int n1,int n2,char Car);

    ~Punt();
        
    void PosaCaracter(char c);
    void PosaCoordenades(int n1, int n2);
    void Dibuixat();
    int TornaX();
    int TornaY();
    char TornaCaracter();
    void ImprimeixDades();
};

void Punt::~Punt()
{
    cout << "Destructor\n";
}

main()
{
    Punt A;
    Punt B(5,4);
    Punt C(3,10,'X');

    A.ImprimeixDades();
    B.ImprimeixDades();
    C.ImprimeixDades();
}
Afegim a la classe la funció ~Punt que serà el destructor dels objectes d'aquesta classe. 

Com que per a aquesta classe no té molt sentit fer aquest métode només hem escrit una instrucció de sortida per pantalla per veure quan s'executa el destructor.

    void Punt::~Punt()
    {
        cout << "Destructor\n";
    }

Així el resultat per pantalla en executar el programa és



que ens indica que el destructor s'executa tres vegades, una per cadascun dels punts declarats A, B i C.

El fet és que el destructor s'executa abans d'acabar la funció main, que és l'àmbit d'existència dels tres punts.

1.6. La classe String. Constructors i destructors amb assignació dinàmica de memòria.

Tot els que hem programat en llenguatge C hem sofert la manera de tractar les cadenes de caràcters i l'assignació de memòria pels strings.

Ja existeix una classe string programada però farem un estudi de programació d'aquesta classe.
 
La classe String: Constructors i destructors amb assignació dinàmica de memòria.
#include <iostream.h>
#include <alloc.h>
#include <string.h>
#include <stdlib.h>

class String
{
    char * Cadena;
    int Longitud;
public:
    String(char * Punter);
    ~String();
    void Posa(char * Punter);
    void ImprimeixDades();
}

String::String(char * Punter)
{
    if ((Cadena = (char *) malloc(strlen(Punter)+1)) == NULL)
    {
        cout << "Falta memòria per a aquest string\n";
        exit(1);
    }
    strcpy(Cadena,Punter);
    Longitud=strlen(Cadena);
}

String::~String()
{
    cout << "Desassignant memòria de dades\n";
    free(Cadena);
}

void String::Posa(char * Punter)
{
    free(Cadena);
    if ((Cadena = (char *) malloc(strlen(Punter)+1)) == NULL)
    {
        cout << "Falta memòria per a aquest string\n";
        exit(1);
    }
    strcpy(Cadena,Punter);
    Longitud=strlen(Cadena);
}

void String::ImprimeixDades()
{
    cout << "Objecte string.\n";
    cout << "Cadena:   " << Cadena << "\n";
    cout << "Longitud: " << Longitud << "\n";
}

main()
{
    String Nom("Pere Lopez Perez");
    Nom.ImprimeixDades();
    Nom.Posa("Adela Lugano Luengo");
    Nom.ImprimeixDades();
}
En primer joc veiem que les propietats d'aquest objecte són un punter a caràcter anomenat Cadena in un enter per a la longitud.

Aquest punter anomenat Cadena haurà d'apuntar a una direcció de memòria de la mida exacta del vector de caràcters que contindrà un objecte de tipus String.

Així farem que sigui el constructor el que s'encarregui de fer la reserva de memòria de la mida exacta mitjançant la instrucció malloc.

Després el constructor copia la cadena i calcula la longitud.

El destructor ha d'encarregar-se de lliurar la memòria usada pel punter Cadena en el moment de destruir l'objecte mitjançant la instrucció free.

Nota: La instrucció cout del destructor pot esborrra-se.

Hem fet el mètode Posa que permet canviar la cadena d'un objecte String. És obvi que les cadena antiga i nova no han de tenir la mateixa longitud. Per tant aquest mètode primer desassigna la memòria utilitzada pel punter Cadena i després fa una reserva de memòria de la longitud de la nova cadena. Després dona valor a les propietats.

També hem fet el mètode auxiliar ImprimeixDades de ajuda al programador.

En el moment d'executar una declaració d'un objecte com String Nom("Pere"); el constructor fa la reserva de memòria per tal de contenir la cadena Pere.

Quan es destrueix l'objecte Nom s'executa el destructor i es lliura la memòria reservada per a la cadena de nom.

El resultat d'executar aquest programa és:

1.6 Introducció a l'herència.

L'herència és el mecanisme pel qual unes classes hereten les propietats i els mètodes d'altra classe. Així la classe que hereta és una classe més específica i l'altra és una classe més general.

Normalment la classe més general es diu classe pare o classe base. La classe més específica i que hereta les propietats i els mètodes rep el nom de classe derivada o classe filla.

Examinem el programa següent:
 

Primera classe amb herència.
#include <iostream.h>

class Pare
{
    int Color;
 public:
    void PosaColor(int n) {Color = n;};
    int DonamColor() {return Color;};
};

class Fill : public Pare
{
    int Mida;
 public:
    void PosaMida(int n){Mida = n;}
    int DonamMida() {return Mida;}
}

main()
{
    Fill Obj;

    Obj.PosaColor(2);
    Obj.PosaMida(12);
    cout << "Color d'Obj: " << Obj.DonamColor() << "\n";
    cout << "Mida d'Obj: " << Obj.DonamMida() << "\n";
}
Veiem que la classe Pare té la propietat Color i els mètodes PosaCololr i DonamColor.

La classe Fill que hereta de la classe Pare amb la declaració 

class Fill : public Pare

La classe Fill té la propietat Color i els mètodes PosaColor i DonamColor ja que els hereta de la classe Pare.

També té, com a propietat i mètodes específics seus, la propietat Mida i els mètodes PosaMida i DonamMida.

A la funció main declarem l'objecte Obj de la classe Fill, i veiem que té accés a totes les propietats i mètodes tant de la classe Pare com als propis i específics seus.

El format per declarar una classe derivada d'una altra inclou l'especificador d'accés a les propietats i mètodes de la classe pare des de la classe filla.

Així en la nostra declaració class Fill : public Pare aquest especificador és la paraula public.

Si una classe derivada té l'especificador public els seus mètodes poden accedir a tots els elements publics de la classe pare però no poden accedir als element privats. També poden accedir als elements publics de la classe pare els objectes de la classe derivada com hem vist en el programa d'exemple.

1.7. Exercicis.

  1. Escriu tots els programes del capítol i prova el resultat.
  2. Separa en un arxiu de capçalera, anomenat punt.h, la declaració de la classe Punt i la definició dels seus mètodes.

    Crea un programa que amb una instrucció include vegi aquesta classe. En aquest programa has de declarar un vector de sis punts que es dibuixaran amb forma de rectangle a la pantalla.
  3. Escriu una classe anomenada DadesPersonals. Aquesta classe ha de tenir com a mínim 4 camps de dades i totes les funcions membres adients per accedir a aquestes dades. També ha de tenir els constructors adients i la funció complementària d'impressió de dades.
  4. Quan tinguis la classe feta i provada fes un altre arxiu de capçalera amb aquesta classe. Prova amb un programa a incloure aquest arxiu nou que has creat.

  5. Afegeix a la classe String els mètodes següents:

  6.  
    String(); Constructor sense paràmetres que assigna una memòria d'un caràcter per a la cadena on posa un '\0'
    String(String * S); Constructor que rep un punter a un objecte de tipus String.
    char * DonamCadena(); Mètode que torna el punter a la cadena de caràcters.
    int DonamLongitud(); Mètode que torna la longitud de la cadena de l'objecte String.

    Fes un arxiu de capçalera nomenat string.h.

  7. Crea una classe anomenada Moble i tres classes filles, per exemple les classes Mesa, Cadira i Llit.

    Has de pensar en les característiques comuns a les tres classes filles. Aquestes característiques són candidates a ser dades de la classe Pare.

    Ara pensa en característiques pròpies de cadascun dels objectes Mesa, Cadira i Llit que no són comunes. Aquestes poden ser dades específiques de cadascun dels objectes.

    En darrer lloc fes com a mínim una funció membre de la classe pare i un de cadascuna de les classes filles.