C++

Na Galipedia, a Wikipedia en galego.
C++
Paradigmamultiparadigma: orientado a obxectos, imperativo, programación xenérica.
Data1985
DeseñadorBjarne Stroustrup
Tipo de datoforte, estático
Postas en funcionamentoGNU Compiler Collection, Microsoft Visual C++, Borland C++ Builder, Dev-C++, C-Free
DialectosISO C++, ANSI C++ (1998), ANSI C++ (2003)
Influído porC, Simula
InfluíuC#, Java, PHP, D

C++ (pronunciado "ce máis máis" ou "ce plus plus") é unha linguaxe de programación deseñada a mediados dos 80 por Bjarne Stroustrup como extensión da linguaxe de programación C.

É unha linguaxe híbrida que se pode compilar. Resulta máis sinxela de aprender para os programadores que xa coñecen C. Actualmente existe un estándar para a linguaxe denominado ISO C++, ao que se adheriron a maioría dos fabricantes de compiladores máis modernos. Existen tamén algúns intérpretes como ROOT. As principais características de C++ son o soporte para programación orientada a obxectos (herdanza, polimorfismo, abstracción, encapsulación) e o soporte para modelos de programación xenérica ("templates"). C++ abrangue tres paradigmas da programación: a programación estruturada, a programación xenérica e a programación orientada a obxectos.

Os modelos defínense da seguinte maneira:

template <parámetros> declaración X

e as instancias con:

X<parámetros>.

Posúe unha serie de propiedades que non se atopan en todas as linguaxe de alto nivel:

  • a posibilidade de redefinir os operadores,
  • a identificación de tipos en tempo de execución (RTTI)

Menciónase a C++ de xeito habitual como unha linguaxe potente xa que permite o traballo tanto a niveis altos como baixos. Non obstante, é das que menos automatismos posúe. A obriga de facer case todo manualmente, ao igual que C, dificulta a súa aprendizaxe.

O nome C++ foi proposto por Rick Masciatti no ano 1983 cando a linguaxe se empregou por vez primeira fóra dun laboratorio científico. Antes usárase o nome de "C con clases". En C, "C++" significa "C + 1", e refírese a que C++ é unha extensión de C. Algúns din que "C++" aínda significa "C", porque "++" neste caso é o operador da post-incrementación, é dicir, aumenta o valor da expresión á que se refire, despois, nas instrucións seguintes. Por isto o valor da expresión neste momento permanece orixinal.

Un exemplo[editar | editar a fonte]

Un exemplo de programa escrito en C++ é o seguinte:

 #include <iostream>
 int main()
 {
    std::cout << "¡Ola mundo!" << std::endl;
    
    return 0; //non é estritamente necesario, pero si talvez aconsellable, de cara a indicar que a execución rematou exitosamente
 }

Conceptos xerais da programación orientada a obxectos[editar | editar a fonte]

  • Clase: é un modelo do que se poden instanciar varios obxectos, os cales toman os atributos e métodos da clase. De forma xeral pode definirse como a representación que fai a programación orientada a obxectos dun obxecto matemático.
  • Obxecto: é a instanciación dunha clase, é dicir, un exemplo concreto das propiedades que pode ter unha clase. Unha clase define unha idea, así como un obxecto é a súa representación.
  • Identidade: permite ao obxecto diferenciarse dos demais.

Tipos primitivos en C++[editar | editar a fonte]

En C e máis en C++ existen dúas clases de tipos primitivos: enteiros e flotantes, que se poden clasificar da seguinte forma:

  1. Enteiros
    1. integer (enteiro)
    2. long integer (enteiro longo)
    3. long long integer (enteiro extralongo, lit. "enteiro longo longo")
    4. short integer (enteiro curto)
    5. character string (cadea de caracteres)
  2. Flotantes
    1. float (IEEE754 Simple) (flotante)
    2. double float (IEEE754 Normal) (dobre flotante)
    3. long double float (IEEE754 estendido) (flotante longo dobre)

O modificador unsigned pódese aplicar a enteiros para obter números sen signo (por defecto os enteiros conteñen signo), co que se permite usar un rango de positivos maior. Segundo a máquina e o compilador usado os tipos primitivos poden ocupar un determinado tamaño en memoria. A seguinte lista ilustra o número de bits que ocupan os distintos tipos primitivos nun PC da familia 386 con gcc.

Tipo Número de Bits
char 8
short 16
int 32
float 32
double 64

Principios[editar | editar a fonte]

Todo programa en C++ debe ter a función main() :

 int main()
 {
     return 0;
 }

O concepto de clase[editar | editar a fonte]

Os obxectos en C++ son abstraídos mediante unha "clase". Segundo o paradigma da programación orientada a obxectos, un obxecto consta de:

  1. Métodos ou funcións
  2. Variables membro

Un exemplo dunha clase

class Punto
{
// Opcional pero recomendado, xa que por defecto os membros son 'private'.
private: 
        // Variable membro privada
        int id;
protected:
        // Variables membro protexidas
        int x;
        int y;
public:
        // Construtor
        Punto();
        // Destrutor
        ~Punto();
        // Funcións membro ou métodos
        int ObterX();
        int ObterY();
};

Construtores[editar | editar a fonte]

Son uns métodos especiais que se executan automaticamente ao crear un obxecto da clase. Na súa declaración non se especifica o tipo de dato que devolven, e posúen o mesmo nome que a clase á que pertencen. De igual forma que outros métodos pode haber varios construtores sobrecargados, aínda que non poden existir construtores virtuais.

Como característica especial á hora de implementar un construtor, xusto despois da declaración dos parámetros, atópase a chamada "lista de inicializadores". O seu obxectivo é chamar aos construtores dos atributos que conforman o obxecto a construír.

Tomando o exemplo da "clase punto", se desexamos que cada vez que se cree un obxecto desta clase as coordenadas do punto sexan igual a cero podemos agregar un construtor como se amosa a continuación:

// Clase Punto
//-----------------------------------------------------------------------
class Punto
{
public:
      // Construtor
      Punto()// Inicializar as variables membro
      : x ( 0 )
      : y ( 0 )
      {
      }

      // Coordenadas do punto
      float x;
      float y;  
};
//-----------------------------------------------------------------------

// Main para demostrar o funcionamiento da clase
# include <iostream>
using namespace std;

int main()
{
    Punto OMeuPunto;
    cout<<"Coordenada X:"<<OMeuPunto.x<<endl;
    cout<<"Coordenada Y:"<<OMeuPunto.y<<endl;
    return 0;
}

Se compilamos e executamos o anterior programa, obteremos unha saída que debe ser similar á seguinte: \\Coordenada X:0 \\Coordenada Y:0 \\

Destrutores[editar | editar a fonte]

Os destrutores son funcións membro especiais chamadas automaticamente na execución do programa, e que polo tanto non deben ser chamadas explicitamente polo programador. O seu cometido: liberar os recursos computacionais que o obxecto de tal clase adquirira en tempo de execución ao expirar este. Os destrutores desaparecen da memoria ao acadaren o fin do ámbito no que está declarado o obxecto.

Funcións membro[editar | editar a fonte]

Función membro é aquela que está declarada en ámbito de clase. Son similares ás funcións habituais agás que o compilador realizase o denominado Name Mangling: cambiase o nome da función engadindo un identificador da clase na que está declarada. Ademais, as funcións membro reciben implicitamente un parámetro adicional: O puntero this, que referencia o obxecto que executa a función.

Modelos[editar | editar a fonte]

Os modelos, ou "templates", son o mecanismo de C++ para implementar o paradigma da programación xenérica. Permiten que unha clase ou función traballe con tipos de datos abstractos, especificando máis adiante cales son os que se queren usar. Por exemplo, é posible construír un vector xenérico que poida conter calquera tipo de estrutura de datos. Desta forma pódense declarar obxectos da clase deste vector que conteñan enteiros, flotantes, polígonos, figuras, fichas de persoal etc. Anteponse template <typename A[=tipo_por_defecto], typename B[=tipo_por_defecto],...> á estrutura de programación (clase, función etc.).

Herdanza[editar | editar a fonte]

  • Herdanza simple
  • Herdanza múltiple

Sobrecarga de operadores[editar | editar a fonte]

É posible definir o comportamento dun operador da linguaxe para que traballe con tipos de datos definidos polo usuario.Estes comportamentos impleméntanse do mesmo xeito que unha función, salvo que esta terá un nome especial: Tipo de dato de devolución operator<token del operador> (parámetros)

  • Operador +
  • Operador ++
  • Operador -
  • Operador --
  • Operador =
  • Operador ==
  • Operador *
  • Operador /
  • Operador %
  • Operador new
  • Operador delete
  • Operador ()
  • Operador []

Biblioteca estándar de modelos (STL)[editar | editar a fonte]

As linguaxes de programación adoitan ter unha serie de bibliotecas integradas para a manipulación de datos a nivel máis básico. En C++, ademais de poder usar as bibliotecas de C, pódese usar a nativa STL (Standard Template Library), propia da linguaxe. Proporciona unha serie de clases parametrizadas (véxase máis arriba modelos) que permite efectuar operacións sobre o almacenado de datos, procesado e fluxos de entrada/saída. A STL é máis un conxunto de bibliotecas ca unha soa. Desta forma unicamente se inclúen no ficheiro executable final aquelas que sexan necesarias para a aplicación que se estea programando, reducindo drasticamente o uso innecesario de memoria.

ostreams / istreams[editar | editar a fonte]

Cabe destacar as clases basic_ostream ebasic_stream, e os obxectos cout e cin, pertencentes a estas clases, respectivamente. Proporcionan a entrada e saída estándar de datos (teclado/pantalla). Tamén está dispoñible cerr, similar a cout, usado para a saída estándar de erros. Estas clases teñen sobrecargados os operadores << e >>, respectivamente, co obxecto de seren útiles na inserción/extracción de datos a ditos fluxos. Son operadores intelixentes, xa que son capaces de adaptarse ao tipo de datos que reciben, aínda que teremos que definir o comportamento de dita entrada/saída para clases/tipos de datos definidos polo usuario. Por exemplo:

ostream& operator<<(ostream& fs,const Punto& punto)
{
  fs << punto.x << "," << punto.y;
  return fs;
}

Desta forma, para mostrar un punto, só teriamos que executar a seguinte expresión:

//...
Punto p(4,5);
//...
cout << "As coordenadas son: " << p << endl;
//...

É posible formatear a entrada/saída, indicando o número de díxitos decimais a mostrar, se os textos se pasarán a minúsculas ou maiúsculas, se os números recibidos están en formato octal ou hexadecimal etc.

fstreams[editar | editar a fonte]

Tipo de fluxo para o manexo de ficheiros. A definición previa de ostreams/istreams é aplicable a este apartado. Existen tres clases: ifstream (só lectura), ofstream (só escritura) e fstream (lectura/escritura).

Poden abrirse pasando ao construtor os parámetros relativos á localización do ficheiro e o modo de apertura:

ios::ate ao abrir o ficheiro, posicionarase ao final ios::trunc Ao abrir, bórrase o contido ios::app Modo "append": abrirase o ficheiro en modo de anexo ios::binary Apertura dun ficheiro binario (isto é un concepto relativo ao sistema operativo en cuestión, logo en moitas ocasións non é necesario)

Para pechar un ficheiro, pode usarse o método close, ou agardar a que o destrutor das clases o peche automaticamente.

sstreams[editar | editar a fonte]

Destacan dúas clases, ostringstream e istringstream. Todo o anteriormente dito é aplicable a estas clases.

Tratan unha cadea como se dun fluxo de datos se tratase. ostringstream permite elaborar unha cadea de texto inserindo datos coma fluxo, e istringstream pode extraer a información contida nunha cadea (pasada como parámetro no seu construtor) co operador >>. Exemplos:

ostringstream s;
s << nome << "," << idade << "," << estatura << "," << punto(5,6) << endl;
cout << s.str();
istringstream s(cadena);
s >> nome >> idade >> estatura >> p;

Contedores[editar | editar a fonte]

Son clases modelos ("template") especiais utilizadas para almacenar tipos de datos xenéricos, sexan cales sexan. Segundo a natureza do almacenado, dispoñemos de varios tipos:

  • Vectores: defínense por
vector<tipo_de_dato> nome_do_vector;

Equivalen aos arrays de calquera linguaxe, con diversas excepcións. Teñen tamaño dinámico, co que se poden inserir elementos aínda que o vector estea cheo. A diferenza dos vectores clásicos a baixo nivel de C, tamén poden lanzar excepcións se se accede a un elemento co rango fóra do vector en cuestión, usando, en vez do operador [], o método at().

  • Colas dobres.
  • Listas.
  • Adaptadores de secuencia.
  • Contedores asociativos: map e multimap.
  • Contedores asociativos: set e multiset.

Métodos comúns e non comúns entre os contedores da STL.

Iteradores[editar | editar a fonte]

Poden considerarse como unha xeneralización da clase de "punteiro". Un iterador é un tipo de dato que permite o percorrido e a busca de elementos nos contedores. Como as estruturas de datos (contedores) son clases xenéricas, e os operadores (algoritmos) que deben operar sobre elas son tamén xenéricos (funcións xenéricas), Stepanov e os seus colaboradores tiveron que desenvolver o concepto de iterador como elemento ou nexo de conexión entre ambos os dous. O novo concepto resulta ser unha especie de punteiros que sinalan aos diversos membros do contedor (punteiros xenéricos que como tales non existen na linguaxe).

Compiladores[editar | editar a fonte]

Un dos compiladores de C++ máis completos é o de GNU[1]: o compilador G++. Este é parte do proxecto Gcc, que engloba varios compiladores para distintas linguaxes.

Actualmente os compiladores máis comúns que se poden atopar para C++ no sistema operativo Windows son Visual C++ e MinGW. Visual C++ pertence a Microsoft e é de pago, mentres que MinGW é unha versión do compilador de GNU adaptada para este sistema operativo. Dev-C++ é un IDE de libre distribución para este compilador e pode ser descargado da súa web oficial Bloodshed gratuitamente.Tamén existe DJGPP, aínda que actualmente está en desuso.

Notas[editar | editar a fonte]

  1. "GNU". www.gnu.org. Consultado o 29 de decembro de 2016. 

Véxase tamén[editar | editar a fonte]

Ligazóns externas[editar | editar a fonte]