Actualizado el 15 de Diciembre del 2018 (Publicado el 23 de Noviembre del 2018)
1.071 visualizaciones desde el 23 de Noviembre del 2018
46,6 KB
21 paginas
Creado hace 25a (05/04/2000)
Tecnología de Objetos - Iniciación a C++
file:///C|/mis documentos/otros/web/initcpp~lala.html
Introducción Rápida a ANSI/ISO C++
Se trata de realizar una introducción rápida al modo de programar de C++. Este texto debe utilizarse
complementariamente al de "Cambios de ANSI/ISO C++ frente a C++ 2.0 de AT&T", en la página de la
asignatura de Tecnología de Objetos. Para comprender este rápido "tour" por C++, es necesario conocer
C.
Programa Hola, Mundo !
El programa Hola, Mundo ! queda como sigue:
#include <iostream>
using namespace std;
void main(void)
{
cout << "Hola, Mundo !" << endl;
}
Respecto a C y a C++, v2.0, destaca la eliminación de la extensión en los ficheros de #include, y la
utilización de namespaces. Los namespaces se corresponden, más o menos, con las unidades de Pascal.
Inicialmente, sólo existe el namespace std, para toda la librería estándar de C++, incluyendo la que hereda
de C. Para utilizar las cabeceras de C, se antepone una 'c' a su nombre. Por ejemplo #include <cstdio>,
#include <cctype>, #include <cstring>. El uso de la stdio está considerado como anticuado por el
estándar ANSI para C++. Que esté definido como anticuado indica que es posible utilizarlo por ahora, pero
que en sucesivas revisiones del lenguaje lo más probable es que desaparezca.
Otra alternativa posible hubiese sido la siguiente, utilizando el operador de acceso, '::' :
#include <iostream>
void main(void)
{
std::cout << "Hola, Mundo !" << std::endl;
}
O también:
#include <iostream>
void main(void)
{
using std::cout;
using std::endl;
cout << "Hola, Mundo !" << endl;
}
Entrada y Salida
1 of 21
5/04/00 21:27
Tecnología de Objetos - Iniciación a C++
file:///C|/mis documentos/otros/web/initcpp~lala.html
Los streams de C se han encapsulado en las clases istream y ostream, con su correspondencia para
archivos en ifstream y ofstream. Existe una clase, la fstream, que permite la entrada y salida a un fichero, es
decir, con acceso directo. La entrada y salida se produce mediante el operador de extracción (>>) e
inserción (<<), respectivamente, lo cuál puede parecer un poco extraño. Estos operadores devuelve en
stream que los llamó, por lo que es posible encadenarlos (como es posible encadenar '+', ya que devuelve la
suma de dos números). Estan sobrecargados para todos los tipos, por lo que no es necesario especificar qué
se escribe y/o se lee, a menos que se desee entrada/salida binaria.
/*
Crea un fichero de texto utilizando varios tipos diferentes de datos
que son formateados a texto automáticamente al escribir con <<
*/
#include <fstream>
using namespace std;
void main(void)
{
int valor;
ofstream fout("texto.txt"); // Creado el objeto fout,
// y abierto el fichero para
// escritura, al ser ofstream
// Leer valor de teclado
cout << "Creando fichero texto.txt\n"
<< "Introduzca un entero" << endl;
cin >> valor;
// Escribir y cerrar el fichero
fout << "Este es un fichero de ejemplo" << '\n'
<< "Valor flotante: " << 5.6 << '\n'
<< "Otro valor: " << valor << endl;
fout.close();
cout << "Finalizada la escritura del fichero texto.txt" << endl;
}
Tipos de Variables y Templates
Enteros
char
short int
int
long int
A todos estos tipos se les puede preceder de la palabra clave signed o unsigned. En
el caso de los int, se gana el bit utilizado para el signo para representar un mayor
rango de números, si se declara unsigned.
Punto flotante:
2 of 21
5/04/00 21:27
Tecnología de Objetos - Iniciación a C++
file:///C|/mis documentos/otros/web/initcpp~lala.html
float
double
long double
Cadenas
std::string
char * o char [] (heredadas de C)
Booleanos
bool
Declaración de variables
Las variables se declaran poniendo el tipo de la variable, el nombre de la misma, y a continuación, la
inicialización, si la hubiera.
int x; // Variable de tipo entero
float f = 0.5; // f es de tipo flotante y vale 0.5
std::string s = "Juan";
Cuando se declara una variable(objeto) de esta forma, la vida de ésta está limitada a su ámbito. Es decir,
si se declara una variable dentro de un método de un objeto o de una función (incluido, main()), la variable
será válida hasta que la función termine.
Se puede necesitar que una variable perdure a la función que lo creó mediante el manejo del heap que se
tenía con el uso en C de malloc() y free(). Los operadores de C++ que realizan esa función se llaman new
y delete.
#include <iostream>
#include <cstring>
#include <typeinfo>
using namespace std;
string *x;
char *y;
y = new char[10];
strcpy(y,"Prueba");
cout << y << endl;
try {
x = new string; // si no hay memoria, new lanza la excepcion badalloc
*x = "Otra Prueba";
cout << *x << endl;
delete x; // Borrar el string
delete[] y; // Borrar los 10 chars reservados
3 of 21
5/04/00 21:27
Tecnología de Objetos - Iniciación a C++
file:///C|/mis documentos/otros/web/initcpp~lala.html
}
catch (bad_alloc &x)
{
cerr << "Error de asignación de memoria." << endl;
}
}
El operador new lanza una excepción si no es posible reservar más memoria. La excepción bad_alloc
está definida en la cabecera typeinfo. Véase más adelante la gestión de excepciones.
Conversión entre tipos
La conversión entre tipos (los cast de C), pueden realizarse utilizando los mecanismos heredados de C,
sin embargo, es aconsejable utilizar los nuevos conversores, puesto que los cast de C se consideran
anticuados:
reinterpret_cast<>()
Este cast es útil entre punteros, en algunas situaciones, con tipos de datos primitivos. Este cast no realiza
(es el único) comprobaciones de ningún tipo, por lo que debe ser utilizado con precaución. Por ejemplo:
int *x = reinterpret_cast<int*>(0x4567);
Estamos convirtiendo un número a una dirección.
static_cast<>()
Es el cast típico para hacer conversiones entre los tipos ptimitivos, también es posible utilizarlo para
realizar casts entre clases derivadas:
class a {};
class b:public a {};
a x;
b y;
a* base;
b* deriv;
base = static_cast<a*>(&y); // No sería necesario el cast
deriv = static_cast<b*>(base); // Legal, correcto en todos los sentidos
// el cast es necesario
deriv = static_cast<b*>(&x); // Legal, pero incorrecto. Errores asegurados.
int z = static_cast<int>(6.5); // No sería necesario el cast
const_cast<>()
Es la única forma en C++ posible de quitarle el const a una variable(u objeto).
4 of 21
5/04/00 21:27
Tecnología de Objetos - Iniciación a C++
file:///C|/mis documentos/otros/web/initcpp~lala.html
const int MAX_SALARIO = 500000;
int f(int &x) { return x + 100000; };
// Esto es ilegal, pero se admite.
// Se supone que el programador sabe lo que hace
// El comportamiento no está definido
cout << "Max. Salario es: " << f(const_cast<int>(MAX_SALARIO))
<< endl;
dynamic_cast<>()
Este cast es un tanto especial, pues forma parte del mecanismo RTTI (Run Time Type Information). Su
propósito es convertir punteros o referencias a objetos que estén relacionados según la herencia, de unos a
otros.
En el caso de manejar punteros, dynamic_cast<> devuelve un NULL si la conversión no se puede
realizar. Si se está tratando de convertir referencias, entonces la excepción bad_cast es lanzada (es
necesario que exista un gestor de excepciones que la recoja).
Supongamos que tenemos dos objetos, de clases diferentes pero relacionadas por herencia. B hereda de A.
#include <iostream>
#include <typeinfo>
using namespace std;
class A { public: virtual ~A() {}; };
class B : public A { public: ~B() {}; };
class C { public: virtual ~C() {}; };
void main(void)
{
B b;
A a;
A *ptr;
C c; // C no está relacionada ni con A ni con B
try {
cout << (ptr = dynamic_cast<A *>(&b)) // Bien
<< endl;
cout << (ptr = dynamic_cast<B *>(ptr))// Bien
<< endl;
cout << (ptr = dynamic_cast<B *>(&a)) // Legal, pero extraño y peligroso.
Falla
<< endl;
cout << (ptr = dynamic_cast<A *>(&c)) // Ilegal, dynamic_cast<> falla
<< endl;
B& refb = dynamic_cast<B&>(a);
}
catch (bad_cast &x)
5 of 21
5/04/00 21:27
Tecnología de Objetos - Iniciación a C++
file:///C|/mis documentos/otros/web/initcpp~lala.html
{
cout << "Error en cast de referencia." << endl;
}
catch (...)
{
cout << "Error indeterminado." << endl;
}
}
La salida del programa es:
0065FDFC
0065FDFC
00000000
00000000
Error en cast de referencia.
Como limitación, dynamic_cast<> no puede ser utilizado si la clase sobre la que se realiza la conversión
no tiene declarados métodos virtuales (ver más arriba static_cast<>, y, más adelante, Polimorfismo), de
ahí que se hayan declarado los destructores de las clases como virtuales, para poder realizar el ejemplo.
La primera conversión, un puntero de una clase derivada a su clase base, funciona sin problemas. Es una
conversión implícita (no necesita cast, en realidad), conocida como downcast, y que es siempre segura (en
una clase derivada siempre se podrá referenciar, como mínimo, su clase base).
En la segunda conversión realizamos un cast de un puntero a una c
Comentarios de: Introducción Rápida a ANSI/ISO C++ (0)
No hay comentarios