C++

C++ és un llenguage de programació dissenyat en 1979 per Bjarne Stroustrup. L'intenció de la seua creació va ser estendre al llenguage de programació C i afegir mecanismes que permeten la manipulació d'objectes. En eixe sentit, des del punt de vista dels llenguages orientats a objectes, C++ és un llenguage híbrit.
Posteriorment es varen afegir facilitats de programació genèrica, que es varen sumar als paradigmes de programació estructurada i programació orientada a objectes. Per açò se sol dir que el C++ és un llenguage de programació multiparadigma.
Actualment existix un estàndart, denominat ISO C++, al que s'han adherit la majoria dels fabricants de compiladors més moderns. Existixen també alguns intérprets, tals com ROOT.
El nom «C++» va ser propost per Rick Mascitti en l'any 1983, quan el llenguage va ser utilisat per primera volta fòra d'un laboratori científic. Abans s'havia usat el nom «C en classes». En C++, l'expressió «C++» significa «increment de C» i es referix a que C++ és una extensió de C.
Característiques de C++
[editar | editar còdic]- La seua sintaxis és heretada del llenguage C.
- Programa orientat a objectes (POO).
- Permet l'agrupació d'instruccions.
- És portàtil i té un gran número de compiladors en diferents plataformes i sistemes operatius.
- Permet la separació d'un programa en mòduls que admeten compilació independent.
- És un llenguage d'alt nivell.
Eixemples
[editar | editar còdic]A continuació se cita un programa d'eixemple Hola món escrit en C++:
#include <iostream>
int main()
{
std::cout << "Hola món!" << std::endl;
return 0;
}En usar la directiva #include se li diu al compilador que busque i interprete tots els elements definits en l'archiu que acompanya la directiva (en este cas, iostream). Per a evitar sobrescribir els elements ya definits en posar-los igual nom, es varen crear els espais de noms o namespace del singular en anglés. En este cas hi ha un espai de noms cridat std, que és a on s'inclouen les definicions de totes les funcions i classes que conformen la biblioteca estàndar de C++. En incloure la sentència using namespace std li estem dient al compilador que usarem l'espai de noms std per lo que no tindrem que incloure-ho quan usem elements d'este espai de noms, com poden ser els objectes cout i cin, que representen el fluix d'eixida estàndar (típicament la pantalla o una finestra de text) i el fluix d'entrada estàndar (típicament el teclat).
La definició de funcions és igual que en C, salve per la distinció de que si main no va a arreplegar arguments, n'hi ha prou en no posar-los, a diferència de C, a on, per seguritat, cal explicitar-ho usant la paraula clau void (int main(void)).[1] El símbol << es coneix com a operador d'inserció, i en este cas, està enviant a cout el text Hola món! per a que ho imprimixca en consola. El mateix operador << es pot usar vàries voltes en la mateixa expressió per a concatenar la funció endl[2] al final, el resultat del qual serà imprimir una tornada de llínea. L'operador += s'utilisa per a sumar el valor de l'expressió a la variable a la que se li aplica. En este cas específic del còdic proporcionat, la llínea «invers += (contrasenya % 10) * 100;» està sumant al valor actual de la variable «invers» el resultat de multiplicar l'últim dígit de la variable «contrasenya» per 100. Açò es repetix per als atres dígits de la contrasenya per a construir el número invertit.
Tipos de senyes
[editar | editar còdic]C++ té els següents tipos fonamentals:
- Caràcters:
char(també és un sancer),wchar_t
- Sancers:
short,int,long,long long - Números en menge flotant:
float,double,long double - Booleanos:
bool - Buit:
void
El modificador unsigned es pot aplicar a sancers per a obtindre números sense signe (per omissió els sancers contenen signe), en lo que es conseguix un ranc major d'número natural.
Tamanys associats
[editar | editar còdic]Segons la màquina i el compilador que s'utilise, els tipos primitius poden ocupar diferents tamanys en memòria. La llista a continuació ilustra el número de bits que ocupen els distints tipos primitius en l'arquitectura x86.[3]
| Tipo | Número de bits |
char |
8 |
short |
16 |
int |
32 |
float |
32 |
double |
64 |
Atres #arquitectura poden requerir distints tamanys de tipos de senyes primitives. C++ no diu res sobre quin és el número de bits en un byte, ni del tamany d'estos tipos; més be, oferix solament les següents «garanties de tipos»:
- D'acort a l'estàndart C99, un tipo
chardeu ocupar exactament un byte compost d'un mínim de 8 bits independentment de l'arquitectura de la màquina. - El tamany reconegut de
charés d'1. És dir,sizeof(char)sempre torna 1. - Un tipo
shortté a lo manco el mateix tamany que un tipochar. - Un tipo
longté a lo manco el doble tamany en bytes que un tiposhort. - Un tipo
intté un tamany entre el deshorti el delong, abdós inclosos, preferentment el tamany d'un apuntador de memòria de la màquina. El seu valor màxim és 2147483647, usant 32 bits. - Un tipo
unsignedté el mateix tamany que la seua versiósigned.
Wchar_t
[editar | editar còdic]Per a la versió de l'estàndart que es va publicar en 1998, es va decidir afegir el tipo de senya wchar_t, que permet l'us de caràcters UNICODE, a diferència del tradicional char, que contempla simplement al còdic de caràcters ASCII estés. A la seua volta, s'ha definit per a la majoria de les funcions i classes, tant de C com de C++, una versió per a treballar en wchar_t, a on usualment es prefixa el caràcter w al nom de la funció (en ocasions el caràcter és un infijo). Per eixemple:
strcpy - wstrcpystd::string - std::wstringstd::cout - std::wcout
cal resaltar que en C es definix wchar_t com:
typedef unsigned short wchar_t;Mentres que en C++ és en sí mateixa un tipo de senya.
La paraula reservada «void»
[editar | editar còdic]La paraula reservada void definix en C++ el concepte de no existència o no atribució d'un tipo en una variable o declaració. És dir, una funció declarada com void no tornarà cap valor. Esta paraula reservada també pot usar-se per a indicar que una funció no rep paràmetros, com en la següent declaració:
int funcion (void);Encara que la tendència actual és la de no colocar la paraula «void».
Ademés s'utilisa per a determinar que una funció no retorna un valor, com en:
void funcion (int parametro);cal destacar que void no és un tipo. Una funció com la declarada anteriorment no pot retornar un valor per mig de return: la paraula clau va sola. No és possible una declaració del tipo:
void t; //Està malEn este sentit, void es comporta de forma llaugerament diferent a com ho fa en C, especialment sobre el seu significat en declaracions i prototips de funcions.
No obstant, la forma especial void * indica que el tipo de senyes és una busca. Per eixemple:
void memòria;
Indica que memòria és una busca a alguna part, a on es guarda informació de algun tipo. El programador és responsable de definir estos «algun», eliminant tota ambigüitat. Una ventaja de la declaració «void *» és que pot representar al mateix temps varis tipos de senyes, depenent de la operació de cast triada. La memòria que hem apuntat en alguna part, en l'eixemple anterior, be podria almagasenar un sancer, un flotant, una cadena de text o un programa, o combinacions d'estos. És responsabilitat del programador recordar qué tipo de senyes hi ha i garantisar l'accés adequat.
La paraula «NULL»
[editar | editar còdic]Ademés dels valors que poden prendre els tipos anteriorment mencionats, existix un valor cridat NULL, siga el cas numèric per als sancers, caràcter per al tipo char, cadena de text per al tipo string, etc. El valor NULL, expressa, por lo regular, la representació d'una Macro, assignada al valor «0».
Tenim llavors que:
void* punter = NULL;
int sancer = NULL;
bool boleana = NULL;
char caracter = NULL;El valor de les variables anteriors nos donaria 0. A diferència de la variable «caracter», que nos donaria l'equivalent a NULL, «
int ObtenerX();
int ObtenerY();
}; </syntaxhighlight>
Constructors
[editar | editar còdic]Són uns métodos especials que s'eixecuten automàticament en crear un objecte de la classe. En la seua declaració no s'especifica el tipo de senya que tornen, i posseïxen el mateix nom que la classe a la que pertanyen. De la mateixa manera que atres métodos, pot haver varis constructors sobrecarregats, encara que no poden existir constructors virtuals.
Com a característica especial a l'hora d'implementar un constructor, just despuix de la declaració dels paràmetros, es troba lo que es diu «llista de inicializadores». El seu objectiu és cridar als constructors dels atributs que conformen l'objecte a construir.
cal destacar que no és necessari declarar un constructor de la mateixa manera que un destructor, puix el compilador ho pot fer, encara que no és la millor forma de programar.
Prenent l'eixemple de la Classe Punt, si desigem que cada volta que es creu un objecte d'esta classe les coordenades del punt siguen igual a zero podem agregar un constructor com es mostra a continuació:
class Punt
{
public:
float x; // Coordenades del punt
float i;
// Constructor
Punt() : x(0), i(0){ // Inicializamos les variables "x" i "i"
}
};
// Main per a demostrar el funcionament de la classe
# include <iostream> // Açò nos permet utilisar "cout"
using namespace std;
int main () {
Punt MiPunto; // vàrem crear un element de la classe Punt cridat MiPunto
cout << "Coordenada X: " << MiPunto.x << endl; // vàrem mostrar el valor acumulat en la variable x
cout << "Coordenada I: " << MiPunto.i << endl; // vàrem mostrar el valor acumulat en la variable i
getchar(); // li indiquem al programa que espere al buffer d'entrada (detindre's)
return 0;
}Si compilamos i eixecutem l'anterior programa, obtenim una eixida que deu ser similar a la següent:
Coordenada X: 0 Coordenada I: 0
Existixen varis tipos de constructors en C++:
- Constructor predeterminat. És el constructor que no rep cap paràmetro en la funció. Si no es definira cap constructor, el sistema proporcionaria un de predeterminat. És necessari per a la construcció d'estructures i contenidors de la STL.
- Constructor de còpia. És un constructor que rep un objecte de la mateixa classe, i realisa una còpia dels atributs del mateix. De la mateixa manera que el predeterminat, si no es definix, el sistema proporciona un.
- Constructor de conversió. Este constructor, rep com a únic paràmetro, un objecte o variable d'un atre tipo distint al seu propi. És dir, convertix un objecte d'un tipo determinat a un atre objecte del tipo que estem generant.
Constructors + Memòria heap Un objecte creat de la forma que es va vore fins ara, és un objecte que viu dins del scope(les claus { }) en el que va ser creat. Per a que un objecte puga seguir vivint quan es traga del scope en el que es va crear, li'l deu crear en memòria heap. Per a açò, s'utilisa l'operador new, el qual assigna memòria per a almagasenar a l'objecte creat, i ademés crida al seu constructor(per lo que se li poden enviar paràmetros). L'operador new s'utilisa de la següent manera:
int main() {
Punt *unPunto = new Punt(); //açò flama al constructor que es descriu més dalt
delete unPunto; //no cal oblidar-se de lliberar la memòria ocupada per l'objecte(vore la secció destructors, més avall)
return 0;
}Ademés, en l'operador new[] es poden crear arrays (coleccions o llistes ordenades) de tamany dinàmic:
Punt assignar(int quants) {
return new Punt[quants]; //assigna un array de 'quants' punts(es diu el constructor que es mostra més dalt), i es retorna.
}Destructors
[editar | editar còdic]Els destructors són funciones membre especials anomenades automàticament en l'eixecució del programa, i per tant no tenen per qué ser cridades explícitament pel programador. Els seus principals comesos són:
- Lliberar els recursos computacionals que l'objecte de dita classe haja adquirit en temps d'eixecució en expirar est.
- Llevar els vínculs que pogueren tindre atres recursos o objectes en est.
Els destructors són invocats automàticament en alcançar el fluix del programa el fi de l'àmbit en el que està declarat l'objecte. L'únic cas en el que es deu invocar explícitament al destructor d'un objecte és quan este va ser creat per mig de l'operador new, és dir, que est viu en memòria heap, i no en la pila d'eixecució del programa. L'invocació del destructor d'un objecte que viu en heap es realisa a través de l'operador delete o delete[] per a arrays. Eixemple:
int main() {
int *unEntero = new int(12); //assignem un sancer en memòria heap en el valor 12
int *arrayDeEnteros = new int[25]; //assignem memòria per a 25 sancers(no estan inicializados)
delete unEntero; //lliberem la memòria que ocupava unEntero
delete[] arrayDeEnteros; //lliberem la memòria ocupada per arrayDeEnteros
return 0;
}Si no s'utilisara l'operador delete i delete[] en eixe cas, la memòria ocupada per unEntero i arrayDeEnteros respectivament, quedaria ocupada sense sentit. Quan una porció de memòria queda ocupada per una variable que ya no s'utilisa, i no hi ha forma d'accedir a ella, es denomina un 'memory leak'. En aplicacions grans, si ocorren molts memory leaks, el programa pot terminar ocupant prou més memòria RAM de la que deuria, lo que no és para res convenient. És per açò, que el maneig de memòria heap deu usar-se conscientment.
Existixen dos tipos de destructors poden ser públics o privats, segons si es declaren:
- Si és públic es diu des de qualsevol part del programa per a destruir l'objecte.
- Si és privat no es permet la destrucció de l'objecte per l'usuari.
L'us de destructors és clau en el concepte d'Adquirir Recursos és Inicializar.
Funciones membre
[editar | editar còdic]Funció membre és aquella que està declarada en àmbit de classe. Són similars a les funcions habituals, en la salvetat de que el compilador realisara el procés de Decoració de nom (Name Mangling en anglés): Canviarà el nom de la funció afegint un identificador de la classe en la que està declarada, podent incloure caràcters especials o identificadors numèrics. Este procés és invisible al programador. Ademés, les funciones membre reben implícitament un paràmetro adicional: La busca this, que referència a l'objecte que eixecuta la funció.
Les funciones membre s'invoquen accedint primer a l'objecte al com referixen, en la sintaxis: myobject.mymemberfunction(), açò és un clar eixemple d'una funció membre.
Cas especial és el de les funciones membre estàtiques. A pesar de que són declarades dins de la classe, en l'us de la paraula clau static no rebran la busca this. Gràcies a açò no és necessari crear cap instància de la classe per a cridar a esta funció, no obstant, solament es podrà accedir als membres estàtics de la classe ya que estos no estan associats a l'objecte sino al tipo. La sintaxis per a cridar a esta funció estàtica és mytype::mystaticmember().
Funcions amigues
[editar | editar còdic]Utilisant la paraula reservada friend es poden declarar funcions externes a una classe, conegudes com a «funcions amigues», que puguen accedir als seus elements privats i protegits com farien si anaren una funció membre. Estes no duen l'especificador d'àmbit en la seua definició, tal i com faria un método membre. Eixemple:
#include <cstdlib>
#include <iostream>
class Punt {
public:
Punt(double x_, double i_): x{x_}, i{i_} {}
double getX() { return x; }
double getY() { return i; }
friend double distancia(Punt& a, Punt& b); // Distància no és una funció membre
private:
double x, i; // Atributs privats
};
// Distància de Manhattan
// Note's que no utilisa especificador d'àmbit de la classe
double distància(Punt& a, Punt& b) {
return std::abs(a.x - b.x) + std::abs(a.i - b.i); // Accedix a atributs privats
}
int main(void) {
Punt a{3,5}, b(6,1);
std::cout << "A(" << a.getX() << ", " << a.getY() << ")
";
std::cout << "B(" << b.getX() << ", " << b.getY() << ")
";
std::cout << "Distància(A,B): " << distància(a, b) << std::endl;
return 0;
}Plantilles
[editar | editar còdic]Les plantilles són el mecanisme de C++ per a implantar el paradigma de la programació genèrica. Permeten que una classe o funció treballe en tipos de senyes abstractes, especificant-se més alvance cuales són els que es volen usar. Per eixemple, és possible construir un vector genèric que puga contindre qualsevol tipo d'estructura de senyes. D'esta forma es poden declarar objectes de la classe d'este vector que continguen sancers, flotants, polígons, figures, fiches de personal, etc.
La declaració d'una plantilla es realisa anteponent la declaració template <typename A,....> a la declaració de l'estructura (classe, estructura o funció) desijat.
Per eixemple:
template <typename T>
T max(const T &x, const T &i) {
return (x > i) ? x : i; //si x > i, retorna x, sino retorna i
}La funció max() és un eixemple de programació genèrica, i daus dos paràmetros d'un tipo T (que pot ser int, long, float, double, etc.) tornarà el major d'ells (usant l'operador >). En eixecutar la funció en paràmetros d'un cert tipo, el compilador intentarà «calçar» la plantilla a eixe tipo de senyes, o be generarà un mensage d'error si fracassa en eixe procés.
Especialisació
[editar | editar còdic]El següent eixemple:
template <typename A> int myfunction(A a);crea una plantilla baix la qual poden ser definides en el còdic de capçalera qualssevol funcions especialisades per a un tipo de senyes com int myfunction(int), int myfunction(std::string), int myfunction(bool), etcétera:
int myfunction (int a) {
return a + 5;
};
int myfunction (std::string a) {
return -a.size();
};
int myfunction (bool a) {
return (a & rand()); //Si a és verdader, torna un número aleatori; en cas contrari torna 0
};Cada una d'estes funcions té la seua pròpia definició (cos). Cada cos diferent, no equivalent («no convertible») correspon a una especialisació. Si una d'estes funcions no fora definida, el compilador tractarà d'aplicar les #conversió de tipos de senyes que li anaren permeses per a «calçar» una de les plantilles, o generarà un mensage d'error si fracassa en eixe procés.
Totes les definicions habilitades d'una plantilla deuen estar disponibles al moment de la compilació, per la qual cosa no és possible actualment «compilar» una plantilla com a archiu d'objecte, sino simplement compilar #especialisació de la plantilla. Per lo tant, les plantilles es distribuïxen junt en el còdic font de l'aplicació. En atres paraules, no és possible compilar la plantilla std::vector< > a còdic objecte, pero sí és possible, per eixemple, compilar un tipo de senyes std::vector<std::string>.
Classes abstractes
[editar | editar còdic]En C++ és possible definir classes abstractes. Una classe abstracta, o classe base abstracta (ABC), és una que està dissenyada solament com a classe pare de les quals es deuen derivar classes filles. Una classe abstracta s'usa per a representar aquelles entitats o métodos que despuix s'implementaran en les classes derivades, pero la classe abstracta en sí no conté cap implementació -- solament representa els métodos que es deuen implementar. Per això, no és possible instanciar una classe abstracta, pero sí una classe concreta que implemente els métodos definits en ella.
Les classes abstractes són útils per a definir interfaços, és dir, un conjunt de métodos que definixen el comportament d'un mòdul determinat. Estes definicions poden utilisar-se sense tindre en conte l'implementació que es farà d'ells.
En C++ els métodos de les classes abstractes es definixen com funcions virtuals pures.
class Abstracta
{
public:
virtual int metodo() = 0;
}
class ConcretaA : public Abstracta
{
public:
int metodo()
{
//fes alguna cosa
return foo () + 2;
}
};
class ConcretaB : public Abstracta
{
public:
int metodo()
{
//una atra implementació
return baz () - 5;
}
};En l'eixemple, la classe ConcretaA és una implementació de la classe Abstracta, i la classe ConcretaB és una atra implementació. Deu notar-se que el = 0 és la notació que ampra C++ per a definir funcions virtuals pures.
Espais de noms
[editar | editar còdic]Una adició a les característiques de C són els espais de nom (namespace en anglés), els quals poden descriure's com a àrees virtuals baix les quals certs noms de variable o tipos tenen validea. Açò permet evitar les ocurrències de conflictes entre noms de funcions, variables o classes.
L'eixemple més conegut en C++ és l'espai de noms std::, el qual almagasena totes les definicions noves en C++ que diferixen de C (algunes estructures i funcions), aixina com les funcionalitats pròpies de C++ (streams) i els components de la biblioteca STL.
Per eixemple:
# include <iostream>
// Les funcions en esta capçalera existixen dins de l'espai de noms std::
namespace el meu_paquet{
int el meu_valor;
};
int main()
{
int el meu_valor = 3;
el meu_paquet::el meu_valor = 4;
std::cout << el meu_valor << '
'; // imprimix '3'
std::cout << el meu_paquet::el meu_valor << '
'; // imprimix '4'
return 0;
}Com pot vore's, les invocacions directes el meu_valor donaran accés solament a la variable descrita localment; per a accedir a la variable de l'espai de noms el meu_paquet és necessari accedir específicament l'espai de noms. Una drecera recomanada per a programes senzills és la directiva using namespace, que permet accedir als noms de variables del paquet desijat en forma directa, sempre i quan no es produïxca alguna ambigüitat o conflicte de noms.
Herència
[editar | editar còdic]Existixen varis tipos d'herència entre classes en el llenguage de programació C++. Estos són:
Herència simple
[editar | editar còdic]L'herència en C++ és un mecanisme d'abstracció creat per a poder facilitar i millorar el disseny de les classes d'un programa. En ella es poden crear noves classes a partir de classes ya fetes, sempre i quan tinguen un tipo de relació especial.
En l'herència, les classes derivades «hereten» les senyes i les funciones membre de les classes base, podent les classes derivades redefinir estos comportaments (polimorfisme) i afegir comportaments nous propis de les classes derivades. Per a no trencar el principi de encapsulamiento (ocultar senyes el coneiximent de les quals no és necessari per a l'us de les classes), es proporciona un nou modo de visibilitat de les senyes/funciones: «protected». Qualsevol cosa que tinga visibilitat protected es comportarà com a pública en la classe Base i en les que componen la jerarquia d'herència, i com privada en les classes que NO siguen de la jerarquia de l'herència.
Abans d'utilisar l'herència, nos tenim que fer una pregunta, i si té sentit, podem intentar usar esta jerarquia: Si la frase <claseB> ÉS-UN <claseA> té sentit, llavors estem davant un possible cas d'herència a on classe A serà la classe base i classe B la derivada.
Eixemple: classes Barco, Acorazar, Carguero, etc. Un Acorazar ÉS-UN Barco, un Carguero ÉS-UN Barco, un Trasatlántico ÉS-UN Barco, etc.
En este eixemple tindríem les coses generals d'un Barco (en C++)
class Barco {
protected:
char* nom;
float pes;
public:
//Constructors i demés funcions bàsiques de barco
};i ara les característiques de les classes derivades, podrien (al mateix temps que hereten les de barco) afegir coses pròpies del subtipo de barco que anem a crear, per eixemple:
class Carguero: public Barco { // Esta és la manera d'especificar que hereta de Barco
private:
float càrrega;
//El restant de coses
};
class Acorazar: public Barco {
private:
int numeroArmas;
int Soldats;
// El restant de coses
};Per últim, cal mencionar que existixen 3 classes d'herència que es diferencien en el modo de manejar la visibilitat dels components de la classe resultant:
- Herència pública (class Derivada: public Base ): En este tipo d'herència es respecten els comportaments originals de les visibilidades de la classe Base en la classe Derivada.
- Herència privada (classe Derivada: private Base): En este tipo d'herència tot component de la classe Base, serà privat en la classe Derivada (les propietats heretades seran privades encara que estes siguen públiques en la classe Base)
- Herència protegida (classe Derivada: protected Base): En este tipo d'herència, tot component públic i protegit de la classe Base, serà protegit en la classe Derivada, i els components privats, seguixen sent privats.
Herència múltiple
[editar | editar còdic]La herència múltiple és el mecanisme que permet al programador fer classes derivades a partir, no d'una sola classe base, sino de vàries. Per a entendre açò millor, posem un eixemple: Quan veus a qui t'atén en una tenda, com a persona que és, podràs supondre que pot parlar, menjar, anar, pero, per un atre costat, com a empleat que és, també podràs supondre que té un cap, que pot cobrar-te diners per la compra, que pot tornar-te el canvi, etc. Si açò ho traslladem a la programació seria herència múltiple (classe amprat_tenda):
class Persona {
...
Parlar();
Caminar();
...
};
class Empleat {
Persona cap;
int sòu;
Cobrar();
...
};
class EmpleadoTienda: public Persona, Empleat {
...
AlmacenarStock();
ComprobarExistencias();
...
};Per tant, és possible utilisar més d'una classe per a que una atra herete les seues característiques.
Sobrecàrrega d'operadors
[editar | editar còdic]La sobrecàrrega d'operadors és una forma de fer polimorfisme. És possible definir el comportament d'un operador del llenguage per a que treballe en tipos de senyes definides per l'usuari. No tots els operadors de C++ són factibles de sobrecarregar, i, entre aquells que poden ser sobrecarregats, es deuen complir condicions especials. En particular, els operadors sizeof i :: no són sobrecargables.
No és possible en C++ crear un operador nou.
Els comportaments dels operadors sobrecarregats s'implementen de la mateixa manera que una funció, llevat que esta tindrà un nom especial: Tipo de senya de devolució operator<token de l'operador>(paràmetros)
Els següents operadors poden ser sobrecarregats:
- Operadors Unarios
- Operador * (de indirección)
- Operador -> (de indirección)
- Operador & (de direcció)
- Operador +
- Operador -
- Operador ++
- Operador --
- Operadors Binarios
- Operador ==
- Operador +
- Operador -
- Operador *
- Operador /
- Operador %
- Operador <<
- Operador >>
- Operador &
- Operador ^
- Operador |
- Operador []
- Operador ()
- Operadors d'Assignació
- Operador =
- Operador +=
- Operador -=
- Operador *=
- Operador /=
- Operador %=
- Operador <<=
- Operador >>=
- Operador &=
- Operador ^=
- Operador |=
Ya que estos operadors són definits per a un tipo de senyes definit per l'usuari, est és lliure d'assignar-los qualsevol semàntica que desige. No obstant, es considera de primera importància que les semàntiques siguen tan semblades al comportament natural dels operadors com per a que l'us dels operadors sobrecarregats siga intuïtiu. Per eixemple, l'us de l'operador unario - deguera canviar el «signe» d'un «valor».
Els operadors sobrecarregats no deixen de ser funcions, per lo que poden tornar un valor, si este valor és del tipo de senyes en el que treballa l'operador, permet l'encadenament de sentències. Per eixemple, si tenim 3 variables A, B i C d'un tipo T i sobrecarreguem l'operador = per a que treballe en el tipo de senyes T, hi ha dos opcions: si l'operador no torna res una sentència com «A=B=C;» (sense les comillas) donaria error, pero si es torna un tipo de senyes T en implementar l'operador, permetria concatenar quants elements es volgueren, permetent alguna cosa com «A=B=C=D=...;»
Standard Template Library (STL)
[editar | editar còdic]- Artícul principal → Standard Template Library.
Els llenguages de programació solen tindre una série de biblioteques de funcions integrades per a la manipulació de senyes a nivell més bàsic. En C++, ademés de poder usar les biblioteques de C, es pot usar la nativa STL (Standard Template Library), pròpia del llenguage. Proporciona una série plantilles (templates) que permeten efectuar operacions sobre l'almagasenat de senyes, processat d'entrada/eixida.
Biblioteca d'entrada i eixida
[editar | editar còdic]Les classes basic_ostream i basic_stream, i els objectes cout i cin, proporcionen l'entrada i eixida estàndar de senyes (teclat/pantalla). També està disponible cerr, similar a cout, usat per a l'eixida estàndar d'errors.
Estes classes tenen sobrecarregats els operadors << i >>, respectivament, en l'objecte de ser útils en l'inserció/extracció de senyes a dits #fluix. Són operadors inteligents, ya que són capaços d'adaptar-se al tipo de senyes que reben, encara que tindrem que definir el comportament de dita entrada/eixida per a classes/tipos de senyes definides per l'usuari. Per eixemple:
ostream& operator<<(ostream& fs, const Punt& punt)
{
return fs << punt.x << "," << punt.i;
}D'esta forma, per a mostrar un punt, solament caldria realisar la següent expressió:
//...
Punt p(4,5);
//...
cout << "Les coordenades són: " << p << endl;
//...És possible formatear l'entrada/eixida, indicant el número de dígits decimals a mostrar, si els texts es passaran a minúscules o mayúscules, si els números rebuts estan en format octal o hexadecimal, etc.
Fstreams
[editar | editar còdic]Tipo de fluix per al maneig de fichers. La definició prèvia de ostreams/istreams és aplicable a este apartat. Existixen tres classes (fichers de llectura, d'escritura o de llectura/escritura): ifstream,ofstream i fstream.
Com obrir un ficher:
(nom_variable_ficher).open("nomene_ficher.dat/txt", ios::in); per a obrir-ho en modo llectura.
(nombrevariablefichero).open("nomene_ficher.dat/txt", ios::out); per a obrir-ho en modo escritura.
Eixemple: f.open("senyes.txt", ios::in);
Com tancar el ficher:
nom_variable_ficher.close();
Eixemple: f.close();
Llegir un ficher:
1-Si és ficher de text pla:
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
ifstream entrada;
entrada.open("textoPlano.txt");
string unString;
while(entrada >> unString)
cout << "Lei: " << unString << endl;
return 0;
}2-Si és un ficher binario(.dat); nom_variable_ficher.read((char*)&nom_variable, sizeof(tipo_variable));
Eixemple:
f.read((char*)&i, sizeof(int));
Escriure un ficher:
1-Si és ficher de text(.txt): nombrevariable<<"text"; a on "text" pot ser també una variable de qualsevol tipo primitiu, o un string.
Eixemple: f<<HOLA;
2-Si és un ficher binario(.dat); nom_variable_ficher.write((char*)&nom_variable, sizeof(tipo_variable));
Eixemple:
f.write((char*)&i, sizeof(int));
Poden obrir-se passant al constructor els paràmetros relatius a l'ubicació del ficher i el modo d'obertura:
Sstreams
[editar | editar còdic]Es destaquen dos classes, ostringstream i istringstream. Tot lo anteriorment dit és aplicable a estes classes.
Tracten a una cadena com si d'un fluix de senyes es tractara. ostringstream permet elaborar una cadena de text insertant senyes com fluix, i istringstream pot extraure l'informació continguda en una cadena (passada com a paràmetro en el seu constructor) en l'operador >>.
Eixemples:
ostringstream s;
s << nom << "," << edat << "," << estatura << "," << punt(5,6) << endl;
cout << s.str();
istringstream s(cadena);
s >> nom >> edat >> estatura >> p;Contenidors
[editar | editar còdic]Són classes plantilles especials utilisades per a almagasenar tipos de senyes genèriques, siguen cuales siguen. Tots els contenidors són homogéneus, és dir, una volta que es declaren per a contindre un tipo de senya determinada, en eixe contenidor, solament es podran ficar elements d'eixe tipo. Segons la naturalea de l'almagasenat, disponem de varis tipos:
- Vectores: Es definixen per
vector<tipo_de_senya> nom_de el_vector;
Són arrays (o llistes ordenades) que es redimensionan automàticament en agregar nous elements, per lo que se li poden agregar «teòricament», infinits elements. Els vectores nos permeten accedir a qualsevol element que continga, per mig de l'operador[]. Deu tindre's en conte que si s'intenta accedir a una posició que excedix els llímits del vector, este no farà cap chequeo, per lo que es deu ser cuidadós en utilisar este operador. Per a assegurar un accés segur al vector, es pot utilisar el método at(int), que llança una excepció de tipo std::out_of_range en cas que açò ocórrega.
Per a afegir elements al final del vector, s'utilisa el método push_back(const T&). Per un atre costat, per a eliminar un element del final del vector, es deu usar el método pop_back().
#include <vector> //llibreria que conté a la classe vector
#include <iostream>
using namespace std;
int main() {
vector<int> intVector; //crea un vector de sancers (sense elements)
intVector.push_back(25); //agrega el sancer 25 al vector
cout << "El primer element és: " << intVector.front() <<
" i el meu vector té " << intVector.size() << " elements." << endl; //imprimix el primer element, retornat pel método front()
intVector.push_back(32); //agregue el sancer 32 al vector
cout << "El primer element és: " << intVector[0] << endl; //imprimix 25
intVector.pop_back(); //elimina l'últim element del vector (i. i. 32)
cout << "Ara tinc: " << intVector.size() << " elements." << endl; //imprimirà 1
return 0;
}- Coes dobles: són semblades als vectores, pero tenen millor eficiència per a agregar o eliminar elements en les «puntes».
deque<tipo_de_senya> nom_de_la_coa;
Ademés dels métodos push_back(const T&) i pop_back(), s'agreguen els métodos push_front(const T&) i pop_front(), que realisen lo mateix que els ya explicats, pero en el començ de la coa.
#include <deque> //llibreria de deques
using namespace std;
int main() {
deque<int> intDeque;
intDeque.push_front(25);
intDeque.push_back(12);
while(intDeque.size())
intDeque.pop_back(); //borra tots els elements
return 0;
}- Llistes: Són eficients a l'hora d'agregar elements. La diferència en les coes dobles, és que són més eficients per a eliminar elements que no estiguen en alguna de les «puntes»
list<tipo_de_senya> nom_de_la_llista;
- Adaptadors de seqüència.
- Contenidors associatius: map i multimap, que permeten associar una «clau» en un «valor». map no permet valors repetits, mentres que multimap si.
map<tipo_de_clau, tipo_de_senya> nom_de el_map; multimap<tipo_de_clau, tipo_de_senya> nom_de el_multimap;
#include <map> //llibreria que conté a map i multimap
#include <string> //llibreria de strings
#include <iostream> //llibreria d'entrada/eixida
using namespace std;
int main() {
map<int, string> intAString;
intAString[1] = "un";
intAString[10] = "dèu";
cout << "En intAString[1]: " << intAString[1] << endl;
cout << "En intAString[10]: " << intAString[10] << endl;
return 0;
}- Contenidors associatius: set i multiset, que oferixen solament la condició de «pertinença», sense la necessitat de garantisar un ordenament particular dels elements que contenen.
Iteradores
[editar | editar còdic]Poden considerar-se com una generalisació de la classe de «busca». Un iterador és un tipo de senya que permet el recorregut i la busca d'elements en els contenidors. Com les estructures de senyes (contenidors) són classes genèriques, i els operadors (algoritmes) que deuen operar sobre elles són també genèrics (funcions genèriques), Stepanov i els seus colaboradors varen tindre que desenrollar el concepte de iterador com a element o nexe de conexió entre abdós. El nou concepte resulta ser una espècie de busques que senyalen als diversos membres del contenidor (busques genèriques que com a tals no existixen en el llenguage).
Algoritmes
[editar | editar còdic]Combinant l'utilisació de templates i un estil específic per a denotar tipos i variables, la STL oferix una série de funcions que representen operacions comunes, i l'objectiu de les quals és «parametrizar» les operacions en que estes funcions es veuen involucrades de modo que la seua llectura, comprensió i manteniment, siguen més fàcils de realisar.
Un eixemple és la funció copy, la qual simplement còpia variables des d'un lloc a un atre. Més estrictament, copia els continguts les ubicacions dels quals estan delimitades per dos iteradores, a l'espai indicat per un tercer iterador. La sintaxis és:
copy (inicie_orige, fi_orige, inicie_destí);
D'esta manera, totes les senyes que estan entre inicie_orige i fi_orige, excloent la senya ubicada en este últim, són copiats a un lloc descrit o apuntat per inici_destine.
Un algoritme molt important que ve implementat en la biblioteca STL, és el sort. L'algoritme sort, ordena qualsevol tipo de contenidor, sempre i quan se li passen com a arguments, des d'a on i fins a a on es vol ordenar-ho.
#include <vector>
#include <deque>
#include <algorithm>
int main() {
vector<int> intVector;
intVector.push_back(60);
intVector.push_back(12);
intVector.push_back(54); //per a este moment, el vector té 60,12,54
sort(intVector.begin(), intVector.end()); //llest, array ordenat, ara té 12,54,60
/Notar que si en lloc d'un vector, anara una deque, s'ordenaria de la mateixa manera. */
}Entre les funcions més conegudes estan swap (variable1, variable2), que simplement intercanvia els valors de variable1 i variable2; max (variable1, variable2) i el seu símil min (variable1, variable2), que retornen el màxim o mínim entre dos valors; find (inici, fi, valor) que busca valor en l'espai de variables entre inici i fi; etcétera.
Els algoritmes són molt variats, alguns inclús tenen versions específiques per a operar en certs iteradores o contenidors, i proveïxen un nivell d'abstracció extra que permet obtindre un còdic més «net», que «descriu» lo que s'està fent, en lloc de fer-ho pas a pas explícitament.
C++11
[editar | editar còdic]- Artícul principal → C++11.
El 12 d'agost de 2011, Herb Sutter, president del comité d'estàndarts de C++, va informar l'aprovació unànim del nou estàndart.[4] La publicació del mateix es va realisar en algun moment del 2011.
Entre les característiques del nou estàndart es poden destacar:
- Funcions lambda;
- Referències rvalue;
- La paraula reservada auto;
- Inicialización uniforme;
- Plantilles en número variable d'arguments.
Ademés s'ha actualisat la biblioteca estàndar del llenguage.
Actualitat i futur
[editar | editar còdic]Plantilla:Aviso En 2011 C++11 va inaugurar una nova era en l'història de C++, iniciant un cicle trienal de llançament de noves versions. A C++11 li va seguir C++14 i després C++17, versió vigent en 2019; C++20 es troba pròxim a estandardisar-se, i ya s'està treballant en la versió C++23. Els compiladors intenten alvançar-se incorporant de manera experimental algunes novetats abans dels llançaments oficials. Pero cada nova versió de C++ inclou tal cantitat d'agregats que els compiladors més alvançats no solen terminar d'incorporar-los fins a dos o tres anys despuix del llançament d'eixa versió.
Diferències de tipos respecte a C
[editar | editar còdic]En C++, qualsevol tipo de senyes que siga declarat complet (fully qualified, en anglés) es convertix en un tipo de senyes únic. Les condicions per a que un tipo de senyes T siga declarat complet són a grans traces les següents:
- És possible al moment de compilació conéixer l'espai associat al tipo de senyes (és dir, el compilador deu conéixer el resultat de sizeof(T)).
- T Té a lo manco un constructor, i un destructor, ben declarats.
- Si T és un tipo compost, o és una classe derivada, o és l'especificació d'una plantilla, o qualsevol combinació de les anteriors, llavors les dos condicions establides prèviament deuen aplicar per a cada tipo de senya constituent.
En general, açò significa que qualsevol tipo de senyes definit fent us de les capçaleres completes, és un tipo de senyes complet.
En particular, i, a diferència de lo que ocorria en C, els tipos definits per mig de struct o enum són tipos complets. Com a tals, ara són subjectes a sobrecàrrega, #conversió implícites, etcétera.
Els tipos enumerats, llavors, ya no són simplement àlies per a tipos sancers, sino que són tipos de senyes úniques en C++. El tipo de senyes bool, igualment, pansa a ser un tipo de senyes únic, mentres que en C funcionava en alguns casos com un àlies per a alguna classe de senya de tipo sancer.
Compiladors
[editar | editar còdic]Un dels compiladors lliures de C++ és el de GNU, el compilador G++ (part del proyecte GCC, que engloba varis compiladors per a distints llenguages). Atres compiladors comuns són Intel C++ Compiler, el compilador de Xcode, el compilador de Borland C++, el compilador de CodeWarrior C++, el compilador g++ de Cygwin, el compilador g++ de MinGW, el compilador de Visual C++, Carbide.c++, entre uns atres.
Entorns de desenroll
[editar | editar còdic]Baix Microsoft Windows
[editar | editar còdic]- CLion
- Visual Studio Code
- Visual Studio
- C++ Builder
- Code::Blocks
- Dev-C++
- Visual C++
- wxDev-C++
- Zinjai
- Open Watcom (IDE i Dialog Editor)
- CodeLite
Baix MacOS
[editar | editar còdic]Baix DOS
[editar | editar còdic]Baix GNU/Linux
[editar | editar còdic]- CLion
- Visual Studio Code
- Code::Blocks
- NetBeans
- Eclipse
- Geany
- Emacs
- Zinjai
- Kdevelop
- Open Watcom (IDE i Dialog Editor)
- CodeLite
Software Creats i Programats en C++
[editar | editar còdic]- Microsoft Edge
- Google Chrome
- μTorrent
- BitTorrent (programa)
- Haiku (sistema operatiu)
- Windows Phone 8.1
- Open Broadcaster Software
- Opera (navegador)
- CATIA
Crítiques
[editar | editar còdic]A pesar de la seua adopció generalisada, molts programadors han criticat el llenguage C++, incloent Linus Torvalds,[5] Richard Stallman,[6] i Ken Thompson.[7] Els problemes inclouen una falta de reflexió o recolector de fem, temps de compilació llents, perceived feature creep,[8] i mensages d'error detallats, particularment de la metaprogramación de plantilla.[9]
Per a evitar els problemes que existixen en C++, i per a aumentar la productivitat,[10] algunes persones sugerixen llenguages alternatius més recents que C++, com D, Go, Rust i Vala.[11]
Vejau també
[editar | editar còdic]Referències
[editar | editar còdic]- ↑ «Overview of main function in C and C++» (en en). mr-kumar-abhishek.github.io. Consultat el 2026-06-27.
- ↑
std::endlés una funció plantilla (function template) que imprimix una tornada de llínea i buida el buffer del fluix. - ↑ «Data Types in C++» (en en). GeeksforGeeks. Consultat el 2026-06-27.
- ↑ http://herbsutter.com/2011/08/12/we-have-an-international-standard-c0x-is-unanimously-approved/
- ↑ Plantilla:Cite mailing list
- ↑ Plantilla:Cite mailing list
- ↑ Andrew Binstock. «Dr. Dobb's: Interview with Ken Thompson». Archivat des d'el original, el 13 de març de 2014. Consultat el 7 de febrer de 2014.
- ↑ Pike, Rob (2012). «Less is exponentially more».
- ↑ Kreinin, Yossi. «Defective C++». Consultat el 3 de febrer de 2016.
- ↑ New Languages, and Why We Need Them, MIT Technology Review
- ↑ The New Native Languages | Dr Dobb's
Bibliografia
[editar | editar còdic]- Bjarne Stroustrup, El llenguage de programació C++, Addison Wesley, Madrit, 1998, ISBN 84-7829-019-2
- Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley Pub Co; Tercera edició (15 de febrer de 2000); ISBN 0-201-70073-5
- Bjarne Stroustrup, The Design and Evolution of C++, Addison-Wesley Pub Cp; Primera edició (29 de març de 1994); ISBN 0-201-54330-3
- Margaret A. Ellis i Bjarne Stroustrup, The Annotated C++ Reference Manual, Addison-Wesley Pub Co; (1 de giner de 1990); ISBN 0-201-51459-1
Enllaços externs
[editar | editar còdic]
Wikimedia Commons alberga contingut multimèdia sobre C++.
- «Cplusplus resources» (en anglés). Consultat el 10 d'abril de 2015.
- «C/C++ Reference=C Programming and C++ Programming» (en anglés). Consultat el 10 d'abril de 2015.
- «TecnoMate.xyz=Curs de Programació C++» (en espanyol). Consultat el 1 de setembre de 2019.
Referències
[editar | editar còdic]- Este artícul conté una traducció derivada de «C++» de Wikipedia en castellà publicada baix la Llicència de documentació lliure de GNU i la Llicència Creative Commons Reconeiximent-CompartirIgual 4.0 Internacional.