Вы находитесь на странице: 1из 136

Una visin global del lenguaje C++

(pensando en sistemas embebidos)

Miriam Ruiz <miriam@debian.org>


Marzo, 2014

Introduccin al lenguaje C++

Qu es C++?

Es un lenguaje de programacin...
De tipado esttico (static typing): Las comprobaciones de
tipos se realizan en tiempo de compilacin, no de ejecucin.
De tipado fuerte (strong typing): Las variables tienen
asociadas un tipo de datos, que define lo que se puede hacer.
De forma libre (free form): La posicin de los caracteres en la
pgina es irrelevante.
Multiparadigma: Soporta ms de un paradigma de
programacin, y la combinacin de los mismos.
Compilado: Es necesario convertirlo al cdigo de la mquina
para poder ejecutarlo.
De propsito general: Puede ser usado para realizar tareas
que no pertenecen a un dominio concreto.
De nivel intermedio: Incorporando caractersticas tanto de
bajo nivel (cercano a la mquina) como de alto nivel (cercano
al ser humano).
Independiente de la plataforma: Write once, compile
anywhere (WOCA)

3 / 136

Principios de diseo de C++

Lenguaje multipropsito tan eficiente y portable como C.


Soportar de forma directa y comprensiva diferentes estilos de
programacin:

Procedimental o funcional
Abstraccin de los datos
Orientada a objetos
Programacin genrica o metaprogramacin

Permitir que la persona que est programando sea la que tome


las decisiones, aunque ello pueda significar que las decisiones
sean equivocadas.
Ser tan compatible con el lenguaje C como sea posible, para
permitir una transicin suave desde este lenguaje.
Evitar las caractersticas que no sean de propsito general, o
que sean especficas de una plataforma.
No incurrir en un sobrecoste o una penalizacin por
caractersticas que no se quieran usar.
No necesitar un sofisticado entorno de desarrollo.
4 / 136

Caractersticas del lenguaje

Uso de operadores, y sobrecarga de los operadores.


4 tipos de gestin de la memoria:

Tipos bsicos: booleanos, caracteres, nmeros enteros,


nmeros en coma flotante. Modificadores: unsigned / signed,
short / long.
Programacin orientada a objetos basada en clases:

Memoria esttica, asignada en tiempo de compilacin


Memoria asignada automticamente, en la pila de ejecucin
Memoria de asignacin dinmica (new/delete o malloc/free)
Uso de garbage collectors a travs de libreras externas

Encapsulacin: public, protected, private, friend.


Herencia jerrquica, que puede ser simple y mltiple. Herencia virtual.
Polimorfismo: Un nico interfaz para diferentes implementaciones.

Esttico: Sobrecarga de operadores. Templates.

Dinmico: Herencia. Funciones virtuales.


Gestin de recursos: Constructores y destructores.

Plantillas o templates: Permiten que una clase o funcin trabaje


con tipos de datos abstractos, especificndose ms adelante
cuales son los que se quieren usar

5 / 136

La evolucin de C++

1980: C with class

1983-1986: CFront 1.1

Excepciones

1996: C++ 98/03

Plantillas o templates

1992: HP C++

Herencia mltiple
Clases abstractas

1991: CFront 3.0

Funciones virtuales
Sobrecarga de operadores
Referencias

1989: CFront 2.0

Clases. Herencia

STL
Espacios de nombres

2011: C++11

Expresiones lambda
Tipos automticos
Hilos de ejecucin (threading)

6 / 136

Etapas en la compilacin de un programa

Cdigo fuente (source code)


Archivos .h, .c, .cpp, .hpp, .cc
Preprocesado (preprocessing)
Archivos con las cabeceras incluidas y las macros
expandidas: .i, .ii
Compilacin (compilation)
Archivos en cdigo ensamblador: .s
Ensamblado (assembling)
Archivos en cdigo mquina: .o
Archivado (library)
Bibliotecas estticas (.a) o dinmicas (.so, .dll)
Enlazado (linking)
Archivos ejecutables (.exe, .elf)

7 / 136

Caractersticas de C++

El modelo de memoria de C++

La memoria consiste en una serie de objetos referenciados por


punteros:

Hay una serie de tipos bsicos predefinidos, y unos mecanismos


para construir estructuras ms complejas a partir de ellos
El almacenamiento de las estructuras se hace de tal forma que la
composicin y la herencia son fciles de implementar

9 / 136

Tipos bsicos de datos en C++

Simples
Booleanos
bool
Enteros (o decimales en coma fija)
char, short, int, long
Enumeraciones
enum
Decimales en coma flotante
float, double, long double
Estructurados
Estructuras de datos: arrays, strings (zero-terminated), union
Definicin de objetos: class, struct
Direcciones
Punteros (*)
Referencias (&)
10 / 136

Modificadores y calificadores de tipos de datos

Modificadores de los tipos de datos:


signed, unsigned, long, short
Calificadores de los tipos de datos:
const: Los objetos de este tipo no pueden ser modificados
const int, const char *
volatile: Indica al compilador que los datos referenciados.
pueden ser alterados de formas no explcitamente
especificadas por el programa.
volatile REGISTER * io_ = 0x1234;
restrict: Indica al compilador que ese puntero es el nico
mecanismo de acceso a los datos a los que apunta.
size_t *restrict ptrA

11 / 136

Punteros
#include <cstdlib>
#include <cstdio>
int main() {
char ch = 'c';
char *chptr = &ch;
int i = 20;
int *intptr = &i;
float f = 1.20000;
float * fptr = &f;
const char * ptr = "I am a string";
printf("\n [%c], [%d], [%f], [%c], [%s]\n",
*chptr, *intptr, *fptr, *ptr, ptr);
return EXIT_SUCCESS;
}

12 / 136

Punteros
#include <cstdlib>
#include <cstdio>
int main() {
char ch = 'c';
char *chptr = &ch;
int i = 20;
int *intptr = &i;

[c], [20], [1.200000], [I], [I am a string]

float f = 1.20000;
float * fptr = &f;
const char * ptr = "I am a string";
printf("\n [%c], [%d], [%f], [%c], [%s]\n",
*chptr, *intptr, *fptr, *ptr, ptr);
return EXIT_SUCCESS;
}

13 / 136

Referencias a variables
#include <cstdlib>
#include <cstdio>
void swap(int & i, int & j) {
int tmp = i;
i = j;
j = tmp;
}
int main() {
int x = 0;
int y = 1;
swap(x,y);
printf("x=%d, y=%d\n", x, y);
int & a = x;
int b = x;
a = 5;
b = 7;
printf("x=%d, y=%d, a=%d, b=%d\n", x, y, a, b);
return EXIT_SUCCESS;
}

14 / 136

Referencias a variables
#include <cstdlib>
#include <cstdio>
void swap(int & i, int & j) {
int tmp = i;
i = j;
j = tmp;
}
int main() {
int x = 0;
int y = 1;
swap(x,y);
printf("x=%d, y=%d\n", x, y);

x=1, y=0

int & a = x;
x=5, y=0, a=5,
int b = x;
a = 5;
b = 7;
printf("x=%d, y=%d, a=%d, b=%d\n", x, y, a, b);
return EXIT_SUCCESS;

b=7

15 / 136

Punteros vs. Referencias

Puntero:
Identifican un contenido ubicado en un lugar de la memoria.
Se define aadiendo el carcter '*' a un tipo de dato.
char * pChar; int * pInt; Shape * pShape;
Se usa por convenio el valor NULL (igual a 0L) para no sealar
ninguna direccin significativa.
Referencia:
No es una variable
Es un alias (o nombre alternativo) de un objeto o dato que ya
existe.
Se define aadiendo el carcter '&' a un tipo de dato.
char & rChar; int & rInt; Shape & rShape;
No siempre necesitan ocupar memoria.
No pueden ser NULL.
No pueden ser modificadas.
A menudo son implementados con punteros por parte de los
compiladores, pero no son lo mismo.
16 / 136

Sobrecarga de funciones

Permite asignar el mismo nombre a funciones distintas, siempre que


tengan diferentes parmetros.
Para el compilador estas funciones no tienen nada en comn a
excepcin del identificador.
Debe haber diferencia en los parmetros.
Si se diferencian nicamente en el valor de retorno, no es suficiente.
Orden de preferencia (reglas de congruencia estndar de argumentos:

Concordancia exacta en nmero y tipo, incluyendo conversiones triviales


como de nombre de matriz a puntero, de nombre de funcin a puntero a
funcin, o de tipo de datos a tipo de datos constante.
Concordancia despus de realizar promociones de los tipos asimilables a
enteros, o de los tipos float a double.
Concordancia despus de realizar conversiones estndares, como de int a
double, de double a long double, de un puntero de una clase derivada a
una superclase, o de un puntero a un puntero a void.
Concordancia despus de realizar conversiones definidas por el usuario o
usuaria.
Concordancia usando la elipsis (...) en funciones con nmero variable de
parmetros.

17 / 136

Expresiones y operadores

Variable: es una entidad que permite a un programa almacenar


informacin, y cuyo valor puede cambiar a lo largo de su ejecucin.
Operando: cada una de las constantes, variables o expresiones que
intervienen en una expresin.
Operador: cada uno de los smbolos que indican las operaciones a
realizar sobre los operandos, as como los operandos a los que afecta.
Expresin: es una combinacin gramaticalmente vlida de operadores
y operandos, que dan como resultado un valor.
Sobrecarga de operadores: es uno de los mecanismos que nos
permite ampliar las capacidades de los lenguajes de programacin
orientados a objetos. En C++, la declaracin y definicin de una
sobrecarga de operador es muy similar a la declaracin y definicin de
una funcin cualquiera.

18 / 136

Operadores en C++

Aritmticos: suma, resta, multiplicacin, divisin y mdulo


Asignacin: Operadores de asignacin simple ('=') y compuestos
Manejo de bits: Manejo de bits (bitwise) entre enteros: complemento,
desplazamientos, AND, XOR y OR
Lgicos: Producen resultados booleanos: AND, OR y NOT. Los
operandos no son siempre evaluados.
De Puntero: Operadores de indireccin (*) y de referencia (&)
Relacionales: ==, !=, <, >, <=, >=
Manejo de memoria: new, delete, new[], delete[]
Modelado de tipos (cast): Convierte datos de un tipo a otro
Otros:

'::' - Acceso a mbito (tambin llamado de resolucin)


'.*' - Dereferencia punteros a miembros de clase
'->*' - Dereferencia punteros a punteros a miembros de clases
'?' - Operador ternario condicional
',' - Operador en la expresiones con coma
'typeid' - Obtiene identificacin de tipos y expresiones en tiempo de
ejecucin
'sizeof' - Obtiene el tamao de memoria utilizado por el operando

19 / 136

Operadores en C++

Operadores unitarios: solo requieren un operando y operan


generalmente de izquierda a derecha (el operador a la izquierda, el
operando a la derecha). C++ dispone de los siguientes operadores
unitarios:
'!' - Negacin lgica
'*' - Indireccin
'&' - Referencia
'~' - Complemento de bits
'++' - Incremento (prefijo o postfijo: ++a, a++)
'--' - Decremento (prefijo o postfijo: --a, a--)
'-' - Menos unitario
'+' - Ms unitario
Operadores binarios: Operadores de asignacin simple ('=') y
compuestos
Operadores ternarios: El nico operador ternario es el operador
relacional ? :

20 / 136

Espacios de nombres (namespace)

Cuando un programa alcanza un gran tamao, la probabilidad de colisiones


en los nombres o identificadores aumenta.
El problema puede llegar a ser an mayor cuando se usan libreras externas.
Un espacio de nombres es una zona donde se pueden declarar y definir
identificadores de cualquier tipo (clases, estructuras, funciones, etc), a la que
se asigna un nombre o identificador propio.
Esto permite diferenciar estos elementos de los que puedan tener
identificadores iguales en otros espacios.
El identificador del espacio, usado como prefijo, permite acceder a los
nombres o identificadores declarados en su interior a travs del operador de
especificador de mbito (::).
Tambin se puede indicar al programa que busque por defecto en los espacios
que se quiera (using namespace).
Incluso sin utilizar explcitamente los subespacios, dentro de un mismo mbito,
C++ distingue automticamente varios espacios de nombres distintos.

El espacio de nombres sencillo, que contiene las variables, funciones,


definiciones de tipo (typedef) y enumeradores (enum).

El espacio de nombres de miembros de clases

El espacio de nombres de miembros de estructuras

El espacio de nombres de miembros de uniones

El espacio de nombres de etiquetas


21 / 136

Espacios de nombres (namespace)


namespace EspacioA
long double LD;
float f(float y)
namespace Sub1 {
namespace Sub2 {
}
namespace EspacioB
long double LD;
float f(float z)
namespace Sub1 {
}

{
{ return y; }
long double LD; }
long double LD; }
{
{ return z; }
long double LD; }

EspacioA::LD = 1.1;
EspacioA::f(1.1);
EspacioB::LD = 1.0;
EspacioB::f(1.1);
EspacioB::X = 1
EspacioA::Sub1::LD = 3;
EspacioA::Sub2::LD = 4;
EspacioB::Sub1::LD = 5;

//
//
//
//
//
//
//
//

Aceso a variable LD del espacio A


Aceso a funcin f de A
Aceso a variable LD del espacio B
Aceso a funcin f de B
Error: Elemento X no definido en B
Aceso a variable LD del subespacio 1 de A
Aceso a variable LD del subespacio 2 de A
Aceso a variable LD del subespacio 1 de A

::EspacioA::LD = 1.1;
::EspacioB::LD = 1.0;

// Acceso comenzando a buscar desde la raiz


// Acceso comenzando a buscar desde la raiz

22 / 136

Espacios de nombres automticos


int x = 1, y = 2, z = 3;
principal
struct E { int x; int y; int z; } e1 = {1, 2, 3};
class C { int x; int y; int z; } c1 = {1, 2, 3};
union U { int x; char y; float z; } u1 = { x };
func(1, 2, 3);

// Espacio
// Estructuras
// Clases
// Uniones

...
int func(int x, int y, int z) {
if (x == 0)
goto x;
return (x + y + z);
x:
return (1 + y + z);

// Etiquetas

23 / 136

Decoracin de Nombres (Name Mangling)

El mecanismo tradicional de asignacin de nombres a los


elementos de C, ya no es vlido para C++ (espacios de
nombres, sobrecarga de funciones).
El compilador cambiar el nombre de la funcin, aadiendo
un identificador del espacio de nombres en el que est declarada,
y de los parmetros aceptados por la funcin.
Cada compilador de C++ realiza la decoracin de los nombres
de una forma diferente, incompatible con los dems. La posible
estandarizacin de la decoracin de los nombres, de todas
formas, sera insuficiente para garantizar la compatibilidad entre
diferentes compiladores (es necesario que haya compatibilidad
tambin en la ABI: gestin de excepciones, distribucin de la
tabla virtual, etc.)
Cuando se quiere buscar la compatibilidad con otros
componentes, se usa la expresin extern C { }
Ejemplos de Name Mangling para diferentes compiladores:
http://en.wikipedia.org/wiki/Name_mangling#How_different_compilers_mangle_the_same_functions

24 / 136

Programacin Orientada a Objetos

Complejidad en la programacin estructurada

26 / 136

Pensar en objetos

La programacin orientada a objetos es un paradigma diferente


de la programacin estructurada, y no una simple ampliacin del
mismo.
Requiere una forma diferente de pensar.
Permite trabajar con sistemas ms complejos de una forma
ms sencilla.
En la programacin estructurada, descomponemos el problema
en acciones, en verbos. En la programacin orientada a objetos,
lo descomponemos en objetos, en nombres.
Al analizar el problema, lo primero que tenemos que ver son las
entidades que lo forman.
Estas entidades poseen un conjunto de propiedades o
atributos, y un conjunto de mtodos mediante los cuales se
puede interaccionar con ellas.
Las entidades se interrelacionan entre ellas mediante mensajes,
respondiendo a ellos mediante la ejecucin de ciertas acciones.
27 / 136

Pensar en objetos

28 / 136

Programacin orientada a objetos

Es un paradigma de programacin que usa los objetos como elemento


base.
Los objetos estn constituidos por propiedades (o variables) y por mtodos
(o funciones).
Las propiedades de un objeto almacenan su estado en un instante
determinado.
Los mtodos de un objeto permiten interaccionar con l para obtener
informacin, y cambiar su estado.
La POO est basada en varias tcnicas, incluyendo:
Herencia: Permite reutilizar el cdigo mediante la especializacin de unos
objetos a partir de otros.
Cohesin: Pretende que cada objeto del sistema se refiera a un nico
proceso o entidad.
Abstraccin: Consiste en aislar un componente de su entorno y del resto
de elementos, hacindo nfasis en qu hace, en lugar de cmo lo hace.
Polimorfismo: Se refiere a la posibilidad de interactuar con objetos
heterogneos de una forma homognea, a travs del mismo interfaz.
Acoplamiento: Cuanto menor acoplamiento entre unos objetos y otros,
ms sencillo ser de desarrollar y mantener.
Encapsulamiento: Se refiere al ocultamiento del estado interno y a la
proteccin del mismo respecto a modificaciones externas.
29 / 136

Un ejemplo de sistema organizado en objetos

30 / 136

Un ejemplo de sistema organizado en objetos

31 / 136

Un ejemplo de sistema organizado en objetos

32 / 136

Clases y Objetos en C++

Clases vs. Objetos

Clase:
Es la definicin abstracta de un tipo de objeto.
Slo tiene sentido en tiempo de programacin.
Definen el aspecto que tendrn los objetos que se creen
durante la ejecucin del programa.
Son una especie de molde o plantilla.
Definen qu atributos tendrn los objetos, y las cosas que se
pueden hacer con l.
Objeto o instancia:
Suponen la concrecin del concepto de clase en un elemento
concreto con caractersticas determinadas.
Existen durante la ejecucin del programa, e interaccionan
entre ellos. Nacen, viven, se comunican y mueren.
El valor concreto de cada atributo es nico e independiente
para cada objeto..
Los conceptos de clase y objetos son anlogos a los de tipo
de datos y variable: definida una clase, podemos crear objetos
de esa clase.
34 / 136

Definicin de una clase en C++


class Rectangle {
public:
Rectangle(int h, int w);
int getHeight();
int getWidth();
private:
int height;
int width;
};
Rectangle::Rectangle(int h, int w) :
height(h), width(w) {
}
int Rectangle::getHeight() {
return height;
}
int Rectangle::getWidth() {
return width;
}

35 / 136

Cmo se almacena una clase en memoria?


class Shape {
public:
Shape(const char* n);
inline const char* getName() const {
return name; }
inline int getLayer() const {
return layer; }
inline char getColor() const {
return color; }
protected:
const char* name;
int layer;
char color;
};

name

layer

color

alignment

36 / 136

Definicin de una clase en C++


Implementacin en C++

class Shape {
public:
Shape();
~Shape();
void draw();
double x, y;

Implementacin equivalente en C

Typedef struct ShapeT {


double x, y;
} Shape;
void Shape_new(Shape * this);
void Shape_delete(Shape * this);
void Shape_draw(Shape * this);

};

37 /37136
/ 70

Constructores

Son funciones miembro especiales que sirven para inicializar los


objetos
Tienen el mismo nombre que la clase a la que pertenecen.
No pueden devolver ningn valor.
No pueden ser heredados.
Cuando no especifiquemos un constructor para una clase, el
compilador crea uno por defecto sin argumentos.
Pueden definirse diferentes constructores para cada clase,
siempre que tengan diferentes parmetros.
Un constructor copia crea un objeto a partir de otro objeto
existente. Si no se especifica ninguno, el compilador tambin
crea uno por defecto.
Se pueden invocar de forma directa de forma excepcional para
inicializar una zona de memoria ya reservada, con un objeto de
un tipo dado.
38 / 136

Destructores

Son funciones miembro especiales que sirven para eliminar un


objeto de una determinada clase.
Tienen el mismo nombre que la clase a la que pertenecen, pero
con el smbolo tilde ('~') delante.
No retornan ningn valor.
No tienen parmetros.
No pueden ser heredados.
Deben ser pblicos.
No pueden ser sobrecargados.
Si la clase tiene algn mtodo virtual, es conveniente declarar el
destructor tambin como virtual.
Son llamados automticamente cuando un objeto deja de existir.

39 / 136

Gestin de recursos

Recursos: Son aquellos elementos que, al ser limitados o tener


que ser compartidos por diferentes componentes del sistema,
han de ser adquiridos y liberados en determinados momentos:
Memoria
Descriptores de archivos
Hilos, procesos, elementos de bloqueo
Eventos, mensajes, modelos
Etc.
Resource Acquisition Is Initialization (RAII): Los recursos son
adquiridos durante la inicializacin de los objetos que los usan o
gestionan (cuando no hay posibilidad de que sean usados antes
de ser disponibles), y liberados cuando se destruyan los mismos
objetos, que se garantiza que sucede incluso cuando hay errores.

40 / 136

Herencia

Permite crear una clase nueva a partir de una ya existente.


Esta nueva clase contiene los atributos y mtodos de la clase primaria.
Este mecanismo permite construir una jerarqua de objetos cada vez
ms especializados.
La principal ventaja de la herencia es la capacidad para definir atributos
y mtodos nuevos para la subclase, que luego se aplican a los atributos
y mtodos heredados.

Herencia Simple

Herencia Mltiple

41 / 136

Herencia simple
class Shape {
public:
Shape(const char * n) : name(n) { }
const char * getName() const { return name; }
protected:
const char * name;
};
class Rectangle : public Shape {
public:
Rectangle(int h, int w);
inline int getHeight() const { return height; }
inline int getWidth() const { return width; }
private:
int height;
int width;
};
Rectangle::Rectangle(int h, int w) :
Shape("Rectangle"), height(h), width(w) { }

42 / 136

Cmo funciona la herencia simple?


class Shape {
public:
Shape(const char * n);
inline const char * getName() const { return
name; }
inline int getLayer() const { return layer; }
inline char getColor() const { return color; }
virtual draw(int x, int y);
protected:
const char * name;
int layer;
char color;
};

name

layer
class Circle : public Shape {
public:
Circle(int r) : Shape("Circle"), radius(r) { }
inline int getRadius() const { return radius; }
virtual draw(int x, int y);
private:
int radius;
};

color

alignment

radius

43 / 136

Implementacin de la herencia
Implementacin en C++

class Shape {
public:
Shape();
~Shape();
void draw();
double x, y;

Implementacin equivalente en C

typedef struct ShapeT {


double x, y;
} Shape;
void Shape_new(Shape * this);
void Shape_delete(Shape * this);
void Shape_draw(Shape * this);;

};
class Box : public Shape {
public:
Box();
~Box();
double area();
double h, w;

typedef struct BoxT {


struct Shape shape;
double h, w;
} Box;
void Box_new(Box* this);
void Box_delete(Box* this);
double Box_area(Box * this);

};

44 /44136
/ 70

Herencia mltiple
class Shape {
public:
Shape(const char * n) : name(n) { }
const char * getName() const { return name; }
protected:
const char * name;
};
class Storage {
public:
Storage(int type);
};
class Rectangle : public Shape, public Storage {
public:
Rectangle(int h, int w);
inline int getHeight() const { return height; }
inline int getWidth() const { return width; }
private:
int height;
int width;
};
Rectangle::Rectangle(int h, int w) :
Shape("Rectangle"), Storage(1), height(h), width(w) { }

45 / 136

Herencia mltiple
class Shape {
public:
Shape(const char * n);
inline const char * getName() const { return name; }
inline int getLayer() const { return layer; }
inline char getColor() const { return color; }
void draw(int x, int y);
protected:
const char * name;
int layer;
char color;
};
class Storage {
public:
bool save(int len, const char * buffer);
bool load(int maxlen, char * buffer);
private:
FILE * file;
};
class Circle : public Shape, public Storage {
public:
Circle(int r) : Shape("Circle"), radius(r) { }
inline int getRadius() const { return radius; }
virtual draw(int x, int y);
private:
int radius;
};

name

layer

color

alignment

file

radius

46 / 136

Implementacin de la herencia mltiple


Implementacin en C++
class Shape {
public:
Shape();
~Shape();
void draw();
double x, y;
};
class Storage {
public:
bool save(int len, const char * buffer);
bool load(int maxlen, char * buffer);
private:
FILE * file;
};
class Box : public Shape, public Storage {
public:
Box();
~Box();
double area();
double h, w;
};

Implementacin equivalente en C
typedef struct ShapeT {
double x, y;
} Shape;
void Shape_new(Shape * this);
void Shape_delete(Shape * this);
void Shape_draw(Shape * this);;
typedef struct StorageT {
FILE * file;
} Storage;
int Storage_save(Storage *this, int len, const
char * buffer);
int Storage_load(Storage *this, int maxlen,
char * buffer);
typedef struct BoxT {
Shape shape;
Storage storage;
double h, w;
} Box;
void Box_new(Box* this);
void Box_delete(Box* this);
double Box_area(Box * this);

47 /47136
/ 70

La necesidad de funciones virtuales


#include <cstdlib>
#include <cstdio>
class Shape {
public:
const char * getName() const{ return "Shape"; };
};
class Rectangle : public Shape {
public:
const char * getName() const { return "Rectangle"; }
};
class Circle : public Shape {
public:
const char * getName() const { return "Circle"; }
};
class Triangle : public Shape {
public:
const char * getName() const { return "Triangle"; }
};
int main() {
Rectangle r1, r2;
Circle c1, c2, c3;
Triangle t1;
Shape * shapes[] = { &r1, &c1, &t1, &r2, &c2, &c3};
for (int i=0; i<sizeof(shapes)/sizeof(Shape); ++i) printf("%s\n", shapes[i]->getName());
return EXIT_SUCCESS;
}

48 / 136

La necesidad de funciones virtuales


#include <cstdlib>
#include <cstdio>
class Shape {
public:
const char * getName() const{ return "Shape"; };
};
class Rectangle : public Shape {
public:
const char * getName() const { return "Rectangle"; }
};
class Circle : public Shape {
public:
const char * getName() const { return "Circle"; }
};
class Triangle : public Shape {
public:
const char * getName() const { return "Triangle"; }
};

Shape
Shape
Shape
Shape
Shape
Shape

int main() {
Rectangle r1, r2;
Circle c1, c2, c3;
Triangle t1;
Shape * shapes[] = { &r1, &c1, &t1, &r2, &c2, &c3};
for (int i=0; i<sizeof(shapes)/sizeof(Shape*); ++i) printf("%s\n", shapes[i]>getName());
return EXIT_SUCCESS;
}

49 / 136

Funciones virtuales
#include <cstdlib>
#include <cstdio>
class Shape {
public:
virtual const char * getName() const = 0;
};
class Rectangle : public Shape {
public:
virtual const char * getName() const { return "Rectangle"; }
};
class Circle : public Shape {
public:
virtual const char * getName() const { return "Circle"; }
};
class Triangle : public Shape {
public:
virtual const char * getName() const { return "Triangle"; }
};
int main() {
Rectangle r1, r2;
Circle c1, c2, c3;
Triangle t1;
Shape * shapes[] = { &r1, &c1, &t1, &r2, &c2, &c3};
for (int i=0; i<sizeof(shapes)/sizeof(Shape); ++i) printf("%s\n", shapes[i]->getName());
return EXIT_SUCCESS;
}

50 / 136

Funciones virtuales
#include <cstdlib>
#include <cstdio>
class Shape {
public:
virtual const char * getName() const = 0;
};
class Rectangle : public Shape {
public:
virtual const char * getName() const { return "Rectangle"; }
};
class Circle : public Shape {
public:
virtual const char * getName() const { return "Circle"; }
};
class Triangle : public Shape {
public:
virtual const char * getName() const { return "Triangle"; }
};

Rectangle
Circle
Triangle
Rectangle
Circle
Circle

int main() {
Rectangle r1, r2;
Circle c1, c2, c3;
Triangle t1;
Shape * shapes[] = { &r1, &c1, &t1, &r2, &c2, &c3};
for (int i=0; i<sizeof(shapes)/sizeof(Shape); ++i) printf("%s\n", shapes[i]->getName());
return EXIT_SUCCESS;
}

51 / 136

Cmo funcionan las funciones virtuales?


class Shape {
public:
Shape(const char * n);
inline const char * getName() const { return name; }
inline int getLayer() const { return layer; }
inline char getColor() const { return color; }
virtual draw(int x, int y);
vptr

protected:
const char * name;
int layer;
char color;
};

name

layer

color

alignment

52 / 136

Cmo funcionan las funciones virtuales?

vptr

type_info

name

draw

type_info

draw
layer

color

alignment

vtable

53 / 136

Implementacin de las funciones virtuales


Implementacin en C++

Implementacin equivalente en C

class Virt {
int a, b;
virtual void foo(int);
};

typedef struct VtableT {


void *(*foo)(Virt * this, int x);
} Vtable;

void f(Virt *v) {


v->foo(x);
}

typedef struct VirtT {


int a, b;
Vtable * vptr;
} Virt;
void f(Virt *v)
{
(*(v->vptr.foo))(v, x);
}

54 /54136
/ 70

Herencia mltiple con mtodos virtuales


class Shape {
public:
Shape(const char * n);
inline const char * getName() const { return name; }
inline int getLayer() const { return layer; }
inline char getColor() const { return color; }
virtual void draw(int x, int y);
protected:
const char * name;
int layer;
char color;
};
class Storage {
public:
bool save(int len, const char * buffer);
bool load(int maxlen, char * buffer);
private:
FILE * file;
};
class Circle : public Shape, public Storage {
public:
Circle(int r) : Shape("Circle"), radius(r) { }
inline int getRadius() const { return radius; }
virtual draw(int x, int y);
private:
int radius;
};

vptr

name

layer

color

alignment

file

radius

55 / 136

Funciones virtuales puras. Interfaces


class IName {
public:
virtual const char * getName() const = 0;
};
class Shape {
public:
Shape(const char * n) : name(n) { }
virtual const char * getName() const { return name; } // IName
protected:
const char * name;
};
class Rectangle : public IName, public Shape {
public:
Rectangle(int h, int w);
inline int getHeight() const { return height; }
inline int getWidth() const { return width; }
private:
int height;
int width;
};
Rectangle::Rectangle(int h, int w) :
Shape("Rectangle"), height(h), width(w) { }

56 / 136

Herencia virtual

Herencia no virtual

Herencia virtual
57 / 136

El problema del diamante: Herencia Virtual


class Storable {
public:
Storable(const char*);
virtual void read();
virtual void write();
virtual ~Storable();
private:
...
}
class Transmitter: public Storable {
public:
void write();
...
}
class Receiver: public Storable {
public:
void read();
...
};
class radio: public Transmitter, public Receiver {
public:
void read();
...
};

58 / 136

El problema del diamante: Herencia Virtual


class Transmitter: public virtual Storable {
public:
void read();
...
}
class Receiver: public virtual Storable {
public:
void read();
...
}
class Radio: public Transmitter, public Receiver {
public:
void read();
...
};
Radio::Radio () :
Storable(10), Transmitter(), Receiver() { }

59 / 136

Modificadores de mtodos de clase

Mtodos en lnea (inline): El cdigo generado para la funcin se


insertar en el punto donde se invoca a la funcin, en lugar de
invocarlo mediante una llamada.
Mtodos constantes (const): Cuando una funcin miembro no
deba modificar ningn elemento de la clase, es conveniente
declararla como constante. Esto impedir que la funcin
modifique los datos del objeto y permitir acceder a este mtodo
desde objetos declarados como constantes.
Mtodos con un valor de retorno constante: Cuando se
devuelvan punteros o referencias a elementos internos que no
deban ser modificados, es conveniente devolverlos como valores
constantes.
Miembros estticos (static): Este tipo de componentes son
esencialmente elementos globales, de los que slo existir una
copia que compartirn todos los objetos de la misma clase.
Constructores explcitos (explicit): Indica al compilador que no
use de forma automtica las conversiones implcitas.
60 / 136

El modificador const
int main() {
int var = 1;
const int const_var = 1;
int * pnt_to_var = &var;
const int * pnt_to_const_var = &var;
int * const const_pnt_to_var = &var;
var = 2;
const_var = 2; // ERROR
*pnt_to_var = 2;
*pnt_to_const_var = 2; // ERROR
*const_pnt_to_var = 2;
pnt_to_var = NULL;
pnt_to_const_var = NULL;
const_pnt_to_var = NULL; // ERROR
return EXIT_SUCCESS;
}

61 / 136

Mtodos constantes
class A {
public:
A() : state(0) {
}
void setState(int new_state) {
state = new_state;
}
int getState() const {
return state;
}
private:
int state;
};
int main() {
A a;
a.setState(5);
a.getState();
const A b;
b.setState(5); // Error
b.getState();
return EXIT_SUCCESS;
}

62 / 136

Mtodos constantes y punteros


class A {
public:
A() : pointer(NULL) {
}
A(const A & other) : pointer(other.pointer) {
}
void setPointer(int * new_pointer) {
pointer = new_pointer;
}
void setPointer(int & new_pointer) {
pointer = &new_pointer;
}
int * getPointer() const {
return pointer;
}
private:
int * pointer;
};
int main() {
int val;
A a;
a.setPointer(&val);
a.setPointer(val);
a.getPointer();
const A b = a;
b.setPointer(&val); // Error
b.setPointer(val); // Error
b.getPointer();
*b.getPointer() = 5;
return EXIT_SUCCESS;
}

63 / 136

Mtodos constantes y retornos constantes


class A {
public:
A() : pointer(NULL) {
}
A(const A & other) : pointer(other.pointer) {
}
void setPointer(int * new_pointer) {
pointer = new_pointer;
}
void setPointer(int & new_pointer) {
pointer = &new_pointer;
}
int * getPointer() const {
return pointer;
}
const int * getConstPointer() const {
return pointer;
}
private:
int * pointer;
};
int main() {
int val;
A a;
a.setPointer(&val);
a.setPointer(val);
a.getPointer();
*a.getPointer() = 5;
*a.getConstPointer() = 5; // Error
const A b = a;
b.setPointer(&val); // Error
b.setPointer(val); // Error
b.getPointer();
*b.getPointer() = 5;
*b.getConstPointer() = 5; // Error
return EXIT_SUCCESS;
}

64 / 136

Mtodos constantes
class A {
public:
A() : pointer(NULL) {
}
A(const A & other) : pointer(other.pointer) {
}
void setPointer(int * new_pointer) {
pointer = new_pointer;
}
void setPointer(int & new_pointer) {
pointer = &new_pointer;
}
int * getPointer() {
return pointer;
}
const int * getPointer() const {
return pointer;
}
private:
int * pointer;
};
int main() {
int val;
A a;
a.setPointer(&val);
a.setPointer(val);
a.getPointer();
*a.getPointer() = 5;
const A b = a;
b.setPointer(&val); // Error
b.setPointer(val); // Error
b.getPointer();
*b.getPointer() = 5; // Error
return EXIT_SUCCESS;
}

65 / 136

Variables y mtodos de clase (static)

Pertenecen a la clase, y no a los objetos que pueden crearse de la


misma.
Sus valores son compartidos por todos los objetos creados a partir
de esa clase.
Van precedidas del modificador static.
Para referenciar una variable esttica, o invocar a un mtodo esttico,
no es necesario crear un objeto de la clase.
class Particle {
public:
Particle();
Particle(const & Particle p);
~Particle();
static inline int NumParticles() const { return num_particles; }
static int num_particles;
};
int Particle::num_particles;
Particle::Particle() { ++num_particles; }
Particle::Particle(const & Particle p) { ++num_particles; }
Particle::~Particle() { --num_particles; }
Particle::NumParticles();
Particle::num_particles();

66 / 136

Relaciones entre clases

Relaciones entre clases: herencia

La clase derivada es semejante a la clase original, pero con algunas


propiedades o mtodos aadidos o modificados. La clase derivada -o
subclase- es una especializacin -o extensin- de la clase base -o
superclase-.
Ejemplo: Una moto, o un coche, son un tipo especial de vehculos.

68 / 136

Relaciones entre clases: herencia


class Vehicle {
public:
int Length;
int Width;
int Height;
int Weight;
};
class MotorVehicle : public Vehicle {
public:
int HorsePower;
int MaxSpeed;
};
class Car : public MotorVehicle {
public:
int NumDoors;
};

69 / 136

Relaciones entre clases: agregacin

La clase agregada tiene una relacin dbil con la clase que contiene la
agregacin. La destruccin de un objeto de la clase contenedora no implica
la destruccin de los objetos que estn agregados por el mismo.
Ejemplo: Yo tengo una relacin con mis amigos, pero no les poseo.

70 / 136

Relaciones entre clases: agregacin


class Car {
public:
int NumDoors;
};
class Road {
public:
static const int MaxNumVehicles = 4;
Vehicle * Vehicles[MaxNumVehicles];
};

71 / 136

Relaciones entre clases: composicin

La composicin define una relacin fuerte entre objetos. El objeto


contenedor posee los objetos que estn contenidos en l, de tal forma que
la destruccin del mismo implica la destruccin de todas sus partes.
Ejemplo: Una mesa contiene un tablero y varias patas.

72 / 136

Relaciones entre clases: composicin


class Wheel {
int Radius;
int Wear;
int Pressure;
};
class Car {
public:
static const int NumWheels = 4;
Wheel Wheels[NumWheels];
int NumDoors;
};

73 / 136

Relaciones entre clases: implementacin


La implementacin de un
interfaz equivale a la
aceptacin de un contrato
entre las partes
relacionadas, de tal forma
que el interfaz define de
qu formas puede
interaccionar la clase con
el resto de objetos.
En C++ no existe
especficamente la figura
del interfaz, y se
implementan con clases
abstractas en las que
todos sus mtodos son
virtuales.
Un interfaz no debe
contener atributos.
Unos interfaces pueden
heredar de otros, y aadir
nuevos mtodos.

74 / 136

Relaciones entre clases: implementacin


class IDrivable {
virtual void SpeedUp(int value) = 0;
virtual void Brake(int value) = 0;
virtual void Turn(int value) = 0;
};
class Car :
public:
virtual
virtual
virtual

public IDrivable {
void SpeedUp(int value) { ... }
void Brake(int value) { ... }
void Turn(int value) { ... }

int NumDoors;
};

75 / 136

Habitualmente se usan todas ellas


class Vehicle {
public:
int Length;
int Width;
int Height;
int Weight;
};
class MotorVehicle : public Vehicle {
public:
int HorsePower;
int MaxSpeed;
};
class Wheel {
int Radius;
int Wear;
int Pressure;
};
class IDrivable {
virtual void SpeedUp(int value) = 0;
virtual void Brake(int value) = 0;
virtual void Turn(int value) = 0;
};
class Car :
public:
virtual
virtual
virtual

public MotorVehicle, public IDrivable {


void SpeedUp(int value) { ... }
void Brake(int value) { ... }
void Turn(int value) { ... }

static const int NumWheels = 4;


Wheel Wheels[NumWheels];
int NumDoors;
};
class Road {
public:
static const int MaxNumVehicles = 4;
Vehicle * Vehicles[MaxNumVehicles];
};

76 / 136

Algunos patrones de diseo

Los Patrones de Diseo

Un patrn de diseo es una solucin estandarizada a un problema


de diseo.
Para que una solucin sea considerada un patrn debe poseer ciertas
caractersticas:

Debe haber comprobado su efectividad resolviendo problemas


similares en ocasiones anteriores.

Debe ser reutilizable, lo que significa que es aplicable a diferentes


problemas de diseo en distintas circunstancias.
Los patrones de diseo pretenden:

Proporcionar catlogos de elementos reusables en el diseo de


sistemas software.

Evitar la reiteracin en la bsqueda de soluciones a problemas ya


conocidos y solucionados anteriormente.

Formalizar un vocabulario comn entre diseadores.

Estandarizar el modo en que se realiza el diseo.

Facilitar el aprendizaje de las nuevas generaciones de


diseadores condensando conocimiento ya existente.
78 / 136

Abstract Factory Pattern (estructural)

Proporciona una interfaz para crear familias de objetos


relacionados o dependientes, sin especificar sus clases
concretas. Se utiliza este patrn cuando se necesita:
Crear una familia de objetos relacionados, diseada para
ser utilizada en conjunto.
Que un sistema sea independiente de la forma en que
sus productos son creados, compuestos o
representados.
Que un sistema sea configurado con una de mltiples
familias de productos.
Proporcionar una biblioteca de clases de productos, y
slo se quiere revelar sus interfaces, no sus
implementaciones.

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Abstract%20Factory%20Pattern

79 / 136

Abstract Factory Pattern (estructural)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Abstract%20Factory%20Pattern

80 / 136

Adapter Pattern (estructural)

Transforma la interfaz de un objeto existente en otra que


los clientes puedan utilizar. De este modo, una clase que
no puede utilizar la primera, puede hacer uso de ella a
travs de la segunda. Se utiliza este patrn cuando se
necesita:
Utilizar una clase existente, pero su interfaz no coincide
Usando composicin
con la que se necesita.
Crear una clase reutilizable que coopera con clases que
no tienen interfaces compatibles.
Utilizar varias subclases existentes, pero como es poco
prctico adaptar cada interfaz, se crea un objeto que
adapte la interfaz de la clase padre.

Usando herencia mltiple


Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Adapter%20Pattern

81 / 136

Adapter Pattern (estructural)

Usando composicin

Usando herencia mltiple


Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Adapter%20Pattern

82 / 136

Decorator Pattern (estructural)

Extiende la funcionalidad de un objeto en forma dinmica,


proporcionando una alternativa flexible a la creacin de
subclases. Se utiliza este patrn cuando se necesita:
Aadir responsabilidades a objetos individuales dinmica
y transparente, es decir, sin afectar a otros objetos.
Retirar responsabilidades de algunos objetos.
La extensin por subclases es poco prctica. Por
ejemplo, un gran nmero de extensiones independientes
son posibles y producira una explosin de subclases por
cada combinacin. Tambin cuando la definicin de
clase puede estar oculta o no disponible para subclases.

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Decorator%20Pattern

83 / 136

Decorator Pattern (estructural)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Decorator%20Pattern

84 / 136

Facade Pattern (estructural)

Proporciona una interfaz unificada para un conjunto de


interfaces de un sistema, y hace que los subsistemas sean
mas facil de usar. Se utiliza este patrn cuando se
necesita:
Minimizar la comunicacin y las dependencias entre
subsistemas.
Proporcionar una interfaz sencilla para un subsistema
complejo.
Eliminar dependencias entre clientes y clases de
implementacin, porque son demasiadas.
Dividir conjuntos de subsistemas en capas.

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Facade%20Pattern

85 / 136

Facade Pattern (estructural)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Facade%20Pattern

86 / 136

Iterator Pattern (de comportamiento)

Proporciona una forma de acceder secuencialmente a los


elementos de un objeto agregado, sin exponer su
representacin interna. Se utiliza este patrn cuando se
necesita:
Para acceder al contenido de un objeto agregado sin
exponer su representacin interna.
Para apoyar recorridos mltiples sobre objetos
agregados.
Para proporcionar una interfaz uniforme para atravesar
diferentes estructuras agregadas (es decir, para apoyar
iteracin polimrfica).

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Iterator%20Pattern

87 / 136

Iterator Pattern (de comportamiento)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Iterator%20Pattern

88 / 136

Observer Pattern (de comportamiento)

Define una dependencia de uno-a-muchos con otros


objetos, de forma que cuando un objeto cambia de estado
todos sus dependientes son notificados y actualizados
automticamente. Se utiliza este patrn cuando se
necesita:
Cuando una abstraccin tiene dos aspectos
dependientes. Encapsular stos en objetos separados
permite modificarlos y usarlos de forma independiente.
Cuando un cambio en un objeto requiere cambiar a los
dems, y no se sabe cules ni cuntos objetos sern.
Cuando un objeto debe ser capaz de notificar a otros
objetos sin hacer suposiciones acerca de quin son
estos objetos. En otras palabras, no se quiere que estos
objetos estn estrechamente acoplados.
Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Observer%20Pattern

89 / 136

Observer Pattern (de comportamiento)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Observer%20Pattern

90 / 136

Singleton Pattern (creacional)

Garantiza que una clase tenga nicamente una instancia y


proporciona un punto de acceso global a la misma. Se
utiliza este patrn cuando se necesita:
Debe haber exactamente una instancia de una clase, y
debe ser accesible a los clientes desde un punto de
acceso conocido.
La instancia nica debe ser extensible por medio de
subclases, y los clientes deben ser capaces de utilizar
esta instancia extendida sin modificar su cdigo.

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Singleton%20Pattern

91 / 136

Singleton Pattern (creacional)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Singleton%20Pattern

92 / 136

State Pattern (de comportamiento)

Altera el comportamiento de un objeto segn el estado


interno en que se encuentre. As, el objeto aparentar
cambiar de clase. Se utiliza este patrn cuando se
necesita:
El comportamiento de un objeto depende de su estado, y
tiene que cambiar su comportamiento en tiempo de
ejecucin en funcin de ese estado.
Se presentan muchos condicionales en el cdigo.

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/State%20Pattern

93 / 136

State Pattern (de comportamiento)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/State%20Pattern

94 / 136

Strategy Pattern (de comportamiento)

Define un conjunto de clases que representan


comportamientos similares: se trata de hacer lo mismo,
pero de diferente manera. Permite que un algoritmo vare
independientemente de los clientes que lo utilizan, y
puedan intercambiarlos en tiempo de ejecucin. Se utiliza
este patrn cuando se necesita:
Muchas clases relacionadas difieren slo en su
comportamiento.
Se necesita diferentes variantes de un algoritmo.
Se presentan muchos condicionales en el cdigo, es
posible que sea necesario aplicar este patrn.
Si un algoritmo utiliza informacin que no deberan
conocer los clientes, la utilizacin del patrn estrategia
evita la exposicin de dichas estructuras.
Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Strategy%20Pattern

95 / 136

Strategy Pattern (de comportamiento)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Strategy%20Pattern

96 / 136

Template Pattern (de comportamiento)

Define el esqueleto de un algoritmo, dejando que las


subclases redefinan ciertos pasos, pero sin cambiar su
estructura. Se utiliza este patrn cuando se necesita:
Aplicar las partes invariables de un algoritmo una vez y
dejar en manos de las subclases la implementacin del
comportamiento que puede variar.
Evitar la replicacin de cdigo mediante generalizacin:
se factoriza el comportamiento comn de varias
subclases en una nica superclase.
Controlar las extensiones de las subclases. El Mtodo
Plantilla utiliza mtodos especiales (mtodos de
enganche o hooks) en ciertos puntos, siendo los nicos
puntos que pueden ser redefinidos y, por tanto, los
nicos puntos donde es posible la extensin.
Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Template%20Pattern

97 / 136

Template Pattern (de comportamiento)

Fuente: http://design-patterns-with-uml.blogspot.com.ar/search/label/Template%20Pattern

98 / 136

La Programacin Genrica

La Programacin Genrica

En su definicin ms sencilla, es un estilo de programacin


centrado en los algoritmos, en el que stos se programan
en funcin de tipos de datos que sern especificados
ms tarde. Este enfoque permite escribir funciones y
estructuras que se diferencian slo en el conjunto de tipos
de datos sobre los que se opera, lo que reduce la
duplicacin de cdigo.
En un sentido ms especfico, describe un paradigma de
programacin en el que los requisitos fundamentales
sobre los tipos se abstraen de ejemplos concretos de
algoritmos y estructuras de datos y se formalizan como
conceptos, y en el que las funciones se implementan de
forma genrica en trminos de estos conceptos.
En C++ se usan templates (o plantillas) para permitir el
uso de tcnicas de programacin genricas.
100 / 136

Ejemplo de templates en C++


template <typename T>
T max(T x, T y) {
return x < y ? y : x;
}
Cuando especializa esa funcin templatizada, el compilador instancia una versin se esa
funcin, en la que el tipo genrico T es sustituido por el tipo de dato que queramos usar:
std::cout << max(3, 7); // el resultado es 7
El compilador genera entonces, de forma automtica, una funcin correspondiente a la
sustitucin de T por int:
int max(int x, int y) {
return x < y ? y : x;
}
La funcin resultante de la especializacin de una funcin genrica puede ser usada
como cualquier otra funcin dentro del lenguaje.
Como se puede ver en el cdigo, los requisitos necesarios para poder usar esta funcin
con un tipo de datos cualquiera son:

Existencia del operador < para el tipo de dato T

Existencia de un operador asignacin para T

101 / 136

Templates: Singleton
template<typename T>
class Singleton {
public:
Singleton(T & instance) {
sfpInstance = &instance;
}
~Singleton() {
sfpInstance = 0L;
}
static T & getInstance()
return *sfpInstance;
}

private:
static T * sfpInstance;
};
template<typename T> T * Singleton<T>::sfpInstance(0L);

102 / 136

Metaprogramacin basada en plantillas

La Metaprogramacin basada en plantillas o Template


metaprogramming (TMP) es una tcnica en la que,
mediante el uso de plantillas, el compilador genera un
cdigo fuente temporal que es aadido al resto del cdigo
del programa antes de que ste sea compilado.
La salida de estas plantillas incluyen constantes en tiempo
de compilacin, estructuras de datos y funciones
completas.
El uso de plantillas puede ser interpretado como ejecucin
en tiempo de compilacin.
Histricamente, la TMP fue descubierta accidentalmente
durante el proceso de estandarizacin del lenguaje C++, al
darse cuenta de que el sistema de plantillas de C++ es
Turing-completo (es decir, que tiene un poder
computacional equivalente a la mquina universal de Turing
y, por tanto, se puede programar cualquier cosa en l).
103 / 136

TMP: Valores y Funciones


#include <cstdlib>
#include <iostream>
struct NumberTwoHolder {
enum { value = 2 };
};
template<int N>
struct ValueHolder {
enum { value = N };
};
template<int X, int Y>
struct Adder {
enum { result = X + Y };
};
struct TypeHolder {
typedef int value;
};
int main() {
std::cout << NumberTwoHolder::value << std::endl; // 2
std::cout << ValueHolder<3>::value << std::endl; // 3
std::cout << Adder<3,4>::result << std::endl; // 7
std::cout << sizeof(TypeHolder::value) << std::endl; // 4
return EXIT_SUCCESS;
}

104 / 136

TMP: Diferentes lneas de ejecucin


template<typename X, typename Y>
struct SameType
{
enum { result = 0 };
};
template<typename T>
struct SameType<T, T>
{
enum { result = 1 };
};

if (SameType<SomeThirdPartyType, int>::result)
{
// ... codigo optimizado, asumiendo que el tipo es un entero

}
else
{
// ... codigo defensivo que no hace ninguna suposicion sobre el tipo

105 / 136

TMP: Recursin
template <unsigned n>
struct factorial
{
enum { value = n * factorial<n-1>::value };
};

template <>
struct factorial<0>
{
enum { value = 1 };
};

int main() {
// Como los calculos se realizan en tiempo de compilacion,
// se puede usar para cosas como el tamao de los arrays
int array[ factorial<7>::value ];
}

106 / 136

TMP: Ejemplo: if en tiempo de compilacin


#include <cstdlib>
#include <iostream>
template <bool Condition, typename TrueResult, typename FalseResult>
class if_;
template <typename TrueResult, typename FalseResult>
struct if_<true, TrueResult, FalseResult> {
typedef TrueResult result;
};
template <typename TrueResult, typename FalseResult>
struct if_<false, TrueResult, FalseResult> {
typedef FalseResult result;
};
int main() {
typename if_<true, int, void*>::result number(3);
typename if_<false, int, void*>::result pointer(&number);
typedef typename if_<(sizeof(void *) > sizeof(uint32_t)), uint64_t, uint32_t>::result
integral_ptr_t;
integral_ptr_t converted_pointer = reinterpret_cast<integral_ptr_t>(pointer);
std::cout << sizeof(void *) << std::endl;
std::cout << sizeof(uint32_t) << std::endl;
std::cout << sizeof(integral_ptr_t) << std::endl;
return EXIT_SUCCESS;
}

107 / 136

TMP: Ejemplo: Comprobaciones estticas


template<class T, class B> struct Derived_from {
static void constraints(T * p) {
B * pb = p; pb = pb;
}
Derived_from() {
void(*p)(T*) = constraints; p = p;
}
};
template<class T1, class T2> struct Can_copy {
static void constraints(T1 a, T2 b) {
T2 c = a; b = a; c = a; b = a;
}
Can_copy() {
void(*p)(T1,T2) = constraints;
}
};
template<class T1, class T2 = T1> struct Can_compare {
static void constraints(T1 a, T2 b) {
a == b; a != b; a < b;
}
Can_compare() {
void(*p)(T1,T2) = constraints;
}
};

108 / 136

TMP: Ejemplo: Lista de Valores (1)


#include <cstdlib>
#include <iostream>
struct NullNumList {};
template<size_t H, typename T>
struct NumList {
enum { head = H };
typedef T tail;
};
template<typename NL>
struct binaryOr;
template<size_t NL_H, typename NL_TAIL>
struct binaryOr<NumList<NL_H, NL_TAIL> > {
enum { value = NL_H | binaryOr<NL_TAIL>::value };
};
template<>
struct binaryOr<NullNumList> {
enum { value = 0 };
};

109 / 136

TMP: Ejemplo: Lista de Valores (y 2)


template<char T>
struct MyList;
template<>
struct MyList<'a'> {
Typedef NumList<1,
NumList<2,
NullNumList> >
data; // 1 | 2 = 3
};
template<>
struct MyList<'b'> {
Typedef NumList<1,
NumList<4,
NumList<8,
NullNumList> > >
data; // 1 | 4 | 8 = 13
};
int main() {
std::cout << binaryOr<MyList<'a'>::data >::value << std::endl; // 3
std::cout << binaryOr<MyList<'b'>::data >::value << std::endl; // 13
return EXIT_SUCCESS;
}

110 / 136

C++ como lenguaje multiparadigma

Qu quiere decir multiparadigma?

C++ no es solamente un lenguaje orientado a objetos, sino


que es compatible con muchos estilos diferentes de
programacin, o paradigmas. La programacin orientada
a objetos es slo uno de ellos.
Ningn paradigma es capaz de resolver todos los
problemas de forma sencilla y eficiente, por lo que es muy
til poder elegir el que ms conviene para cada tarea.
Habitualmente se combinan diferentes tipos de
paradigmas dentro de los programas.

112 / 136

C++ como ensamblador de alto nivel

C++ permite programar de una forma muy cercana al propio funcionamiento


de la mquina.
La programacin imperativa describe las operaciones en trminos del estado
de un programa, y de operaciones que cambian dicho estado. Los programas
imperativos son un conjunto de instrucciones que le indican al ordenador cmo
realizar una tarea.
El hardware habitual de los ordenadores actuales implementa el concepto de
mquina de Turing y, por tanto, est diseado para ejecutar cdigo escrito en
forma imperativa.
C++ hereda de C un sistema de tipos de datos que se pueden mapear de una
forma muy cercana a los tipos nativos de la CPU, y operaciones primitivas que
tambin se pueden mapear de una forma muy directa a instrucciones en cdigo
mquina.
Se pueden incorporar instrucciones directas en ensamblador dentro del
programa, lo que permite un control muy exacto del programa resultante, a
cambio de perder en claridad y portabilidad.
Esta forma de programacin puede resultar muy crptica y oscura a veces, pero
a la hora de hacer desarrollos de bajo nivel, incluidos los componentes que
interaccionan con el hardware o aquellos que necesitan un alto nivel de
optimizacin, es imprescindible.

113 / 136

C++ como ensamblador de alto nivel


uint8_t mask = 0x3F;
mask |= 0x40;
uint16_t reg1 = 0x25;
uint16_t reg2 = reg1 << 3;
if (tp->pending & tp->ewmask) != 0) {
do_e(tp);
} else {
queue->add(tp);
}

114 / 136

Programacin estructurada en C++

Este es el estilo de programacin clsico heredado de C. El programa


comienza en una funcin principal, llamada main, que llama a otras funciones,
que a su vez llaman a otras.
El flujo de ejecucin del programa est controlado por expresiones
estructuradas como for, while, switch o until.
Las variables son visibles dentro del bloque en el que han sido definidas, y no
son accesibles directamente desde fuera de ese bloque.
Las funciones tienen un nico punto de entrada, y una nica forma de
terminacin.
Este estilo de programacin incluye tambin la estructuracin de los datos.
Para ello existe un mecanismo, struct, que permite organizar los datos en
forma de una nica entidad que los englobe, y que puede ser copiada por
valor, transferida por valor a otras funciones, etc.

115 / 136

Programacin estructurada en C++


void funcC(void) {
for (int i = 0; i < MaxI(); ++i) {
if (funcB(i)) {
doSomething()
}
}
while (funcA()) {
whatever();
};
}

116 / 136

Abstraccin de datos en C++

Consiste agrupar en componentes, de forma unificada, tanto los datos


como los mtodos que permiten manipularlos.
Ejemplos clsicos de esta abstraccin de tipos de datos son las pilas y las
listas.
En lugar de usar estructuras de datos con funciones separadas para manipular
estos datos, las funciones son incorporadas al propio componente que los
contiene. En el caso de una pila, estas funciones seran las operaciones push
y pop, por ejemplo.
El sello distintivo de este paradigma es el uso de tipos de datos concretos. Por
ello, las funciones virtuales apenas se usan, y los objetos son copiados y
asignados libremente.
En concreto, los operadores de copia y construccin existen para poder dar
soporte a este estilo de programacin, y Tienen una gran importancia en
permitir la creacin de nuevos tipos de datos que se comporten casi igual que
los tipos nativos, como int o double.

117 / 136

Abstraccin de datos en C++


struct Queue {
Queue();
void push(int v);
int pop();
static const MAX = 29;
int data[NAX]
};
Queue q;
q.push(5);
q.push(3);
int a = q.pop();

118 / 136

Programacin orientada a objetos en C++

La programacin orientada a objetos en C++ se implementa en base a


clases.
Las propiedades de los objetos se almacenan en estructuras (class o struct).
En ellas se almacena de forma estructurada toda la informacin relativa a un
objeto.
C++ da soporte tambin a mtodos y propiedades de clase (que son, en
muchos aspectos, semejantes a las variables y funciones globales).
Los mensajes entre objetos se implementan en base a mtodos o funciones,
que se comportan de una forma parecida a las funciones de C, aadindoles
un primer parmetro oculto que referencia la estructura de datos que contiene
las propiedades del objeto, y que pueden llevar informacin adicional en forma
de parmetros.
Se puede restringir el acceso a las propiedades o a los mtodos de una clase
mediante los modificadores public, protected y private.
El paradigma de orientacin a objetos hace un uso extensivo de las funciones
virtuales y del polimorfismo.
En C++, los tipos polimrficos son la referencia y el puntero. Hay que tener
mucho cuidado con ellos a la hora de copiar o asignar objetos, puesto que la
asignacin de un objeto derivado a una clase base puede implicar que el objeto
sea truncado, copindose slo la informacin perteneciente al tipo base.

119 / 136

Programacin orientada a objetos en C++


class IDrivable {
virtual void SpeedUp(int value) = 0;
virtual void Brake(int value) = 0;
virtual void Turn(int value) = 0;
};
class Car :
public:
virtual
virtual
virtual

public IDrivable {
void SpeedUp(int value) { ... }
void Brake(int value) { ... }
void Turn(int value) { ... }

int NumDoors;
};
IDrivable auto = new Car();
Car.SpeedUp(15);
120 / 136

Programacin genrica en C++

La programacin genrica es la programacin con conceptos (concepts) .


Los algoritmos son abstraidos, para permitirles trabajar sobre cualquier tipo de
dato que pueda satisfacer el interfaz usado por el algoritmo.
En la librera estndar de C++, hay componentes como container, iterator o
algorithm que forman una triada para dar soporte a la programacin genrica.
Este paradigma est construido tambin sobre la abstraccin de los datos, pero
tomndola en una direccin diferente a la de la programacin orientada a
objetos.
El mecanismo de C++ que permite soportar la programacin genrica son las
plantillas o templates, que es el mecanismo de parametrizacin de tipos
provisto por el lenguaje.
EL uso de plantillas tiene un precio: las libreras son ms difciles de usar, y los
problemas se traducen en mensajes de error confusos.
Tal y como estn definidas en C++98, las plantillas no tienen restricciones, y la
comprobacin de tipos se realiza al final del proceso de compilacin, es decir,
despus de combinar la plantilla con definicin del tipo de datos.
C++11 incluye los conceptos (concepts) para expresar el comportamiento
sintctico y semntico de los tipos, y para restringir los parmetros de tipo que
se pueden usar en una plantilla de C++.

121 / 136

Programacin genrica en C++


template <unsigned n>
struct factorial
{
enum { value = n * factorial<n-1>::value };
};
template <>
struct factorial<0>
{
enum { value = 1 };
};
int main() {
// Como los calculos se hacen en tiempo de compilacion,
// se puede usar para cosas como el tamao de los arrays

int array[ factorial<7>::value ];


}
122 / 136

Programacin funcional en C++

La esencia de la programacin funcional consiste en trabajar con valores, en


lugar de hacerlo con identidades.
La principal diferencia entre un valor y una identidad, es que el valor es
constante e inalterable (el nmero 1 es siempre el mismo), mientras que el
valor asociado a una identidad puede cambiar (el contenido de una variable).
El modificador const provee un mtodo eficiente para el paso de objetos
grandes a la hora de trabajar con sus valores, y no con sus identidades.
Mediante el uso del modificador const, C++ permite tipos de datos inmutables,
semejantes a los que se encuentran en la mayor parte de los lenguajes de
programacin funcionales.
Sin embargo, trabajar con estos tipos de datos inmutables en C++ es difcil y
engorroso. En particular, la necesidad de hacer copias completas de objetos de
gran tamao para cada pequeo cambio, no es eficiente.
C++11 incorpora una serie de herramientas nuevas para facilitar el estilo de
porgramacin funcional en C++. La ms importante de ellas quizs sean las
funciones lambda (tambin llamadas closures o funciones annimas). Esta
funcionalidad, de todas formas, ya estaba accesible en base al uso de functors,
muy poderosos pero menos prcticos de usar. De hecho, entre bastidores, C++
implementa las funciones lambda como functors.
C++11 tambin provee estructuras para trabajar con informacin compartida,
de tal forma que se facilite el trabajo eficiente con tipos de datos inmutables.
123 / 136

Programacin funcional en C++


#include <iostream>
// abstract base class for a ontinuation functor
struct continuation {
virtual void operator() (unsigned) const = 0;
};
// accumulating continuation functor
struct accum_cont: public continuation {
private:
unsigned accumulator_;
const continuation &enclosing_;
public:
accum_cont(unsigned accumulator,
const continuation &enclosing)
: accumulator_(accumulator),
enclosing_(enclosing) {
};
virtual void operator() (unsigned n) const {
enclosing_(accumulator_ * n);
};
};

int main ()
{
// continuation which displays argument
// when called
struct disp_cont: public continuation {
virtual void operator() (unsigned n) const {
std::cout << n << std::endl;
};
} dc;
// continuation which multiplies argument by 2
// and displays it when called
struct mult_cont: public continuation {
virtual void operator() (unsigned n) const {
std::cout << n * 2 << std::endl;
};
} mc;
fact_cps(4, dc); // prints 24
fact_cps(5, mc); // prints 240
return 0;
}

void fact_cps (unsigned n, const continuation &c)


{
if (n == 0)
c(1);
else
fact_cps(n - 1, accum_cont(n, c));
}

Factorial Functor
Fuente: http://stackoverflow.com/questions/1981400/functional-programming-in-c

124 / 136

C++ en Sistemas Embebidos

Programacin eficiente en C++

Lo que se haga en tiempo de compilacin (o de ensamblado, o enlazado) tiene menor


coste que lo que se tenga que hacer en ejecucin (run-time).
Que el coste mnimo de alguna caracterstica de C++ sea bajo, no implica que la
implementacin real de un compilador concreto sea la ms optimizada.
Las optimizaciones de los compiladores mejoran con el tiempo, y pueden dejar
obsoletas algunas recomendaciones (como el uso de register e inline).
Verifica el coste real de la compilacin del cdigo en un compilador determinado.
Caractersticas de C++ que no tienen por qu tener un coste adicional:

Variables static const inicializadas (en vez de #define del preprocesador)

Ubicacin arbitraria de las declaraciones

Referencias (en lugar de punteros)

Espacios de nombres

Operadores new/delete (en vez del uso de malloc/calloc/free)

Sobrecarga de funciones
Caractersticas de C++ con un coste adicional bajo:

Inicializacin/Conversin/Terminacin de variables

Posicionamiento inline del cdigo

Herencia mltiple

Uso de templates o plantillas


Caractersticas de C++ con un coste adicional alto:

Run-Time Type Identification (RTTI)

Uso de excepciones (EH, Exception Handling)

126 / 136

Los compiladores y los tipos de datos en C++

Los compiladores tienen cierta libertad para elegir el tamao de los tipos
de datos comunes

sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)


char por lo menos de tamao suficiente para el conjunto de caracteres bsico
short al menos de 16 bits
long al menos de 32 bits

C++ permite realizar operaciones entre variables de diferente tamao, o


combinando con y sin signo.
unsigned char a = 200;
int b = -20;
a = a + b;

Los compiladores generalmente cambian cada tipo a uno de ms bits que


incluye todos los valores posibles del original.
La conversin de tipos se hace frecuentemente de forma transparente.
Las reglas de conversin de tipos son complejas, tienen en cuenta la
eficiencia, y dependen del compilador usado.
C++ hereda de C el uso de enteros y punteros como booleanos,
producindose una conversin transparente de tipos.
Los nmeros en coma flotante dependen del compilador y la arquitectura.
Uso de modificadores que afectan al almacenamiento y acceso a la memoria,
y a las optimizaciones a aplicar: const, volatile.
127 / 136

La gestin de la memoria en C++

Existen tres tipos principales de memoria en C++:

Memoria global (variables estticas, tienen asignado un espacio en la


memoria al enlazar, y viven durante toda la ejecucin del programa).

Memoria dinmica o 'heap' (es asignada dinmicamente con las funciones


malloc/free o con los operadores new/delete).

Memoria local (variables automticas, se almacenan en la pila, o 'stack')

Normalmente, el stack crece en en sentido, y el heap en otro, pero el heap


puede estar fragmentado, ya que no es una pila
En la mayora de las plataformas, al llamar a una funcin, se reserva una
porcin de memoria en el stack (llamada 'stack frame') para guardar:

La direccin de retorno.

Los parmetros que se le pasan a la funcin.

Las variables de la funcin que slo viven mientras se ejecuta esta.


Ni C ni C++ ponen ninguna restriccin de acceso a la memoria. Ni se
comprueba automticamente que ste se efecte dentro de los lmites de los
arrays, ni que los punteros para acceder a la memoria tienen sentido.
La gestin de la memoria es decidida por el compilador, que ajusta el
tamao de los tipos de datos a lo que ms le convenga para adecuarse a sus
criterios de optimizacin, y que tambin suele dejar huecos vacos entre las
zonas de memoria usadas ('padding'), para optimizar su acceso. A menudo los
compiladores tienen opciones para configurar esto ('pack').
128 / 136

El modelo de memoria en C++

El modelo de memoria de C++ es la especificacin de cundo y por qu se


lee o se escribe en la memoria real en la ejecucin de un programa en C++.
Antes de C++11, el modelo de memoria de C++ era el mismo que el de C:

Slo se especifica el comportamiento de las operaciones de memoria


observables por el programa actual.

No se dice nada acerca de los accesos concurrentes a la memoria


cuando varios procesos, subprocesos o tareas acceden a la misma (no
existe la nocin de memoria compartida, de procesos compartidos ni de
hilos de ejecucin).

No se ofrece ninguna forma de especificar un orden de acceso a memoria


(las optimizaciones del compilador incluyen el movimiento de cdigo, y los
procesadores modernos pueden reordenar los accesos).

Por tanto, antes de C++11 slo se tiene en cuenta la existencia de un solo


proceso, con un nico hilo de ejecucin, y no se debe depender de un
orden especfico de acceso a variables en la memoria.
Puntos importantes a la hora de tener en cuenta la memoria:

Atomicidad: Qu instrucciones tienen efectos indivisibles?

Visibilidad: Cundo son visibles los efectos de un hilo para otro?

Orden: Bajo qu condiciones los efectos de las operaciones pueden


aparecer fuera de orden para otro hilo?

129 / 136

Estndares de programacin en C++

Motor Industry Software Reliability Association (MISRA C++): Forman un


subconjunto seguro del lenguaje C++ para el desarrollo de los sistemas crticos
de seguridad en aplicaciones embebidas. Funciona en base a una serie de
restricciones sobre el uso del lenguaje. La norma se basa en estndares de
codificacin establecidos como MISRA C, Joint Strike Fighter Air Vehicle C++
coding standard (JSF++) de Lockheed Martin y High-Integrity C++ coding
standard (HICPP) de PRQA.
Joint Strike Fighter Air Vehicle C++ (JSF++ AV++): Desarrollado por
Lockheed Martin para ayudar a desarrollar cdigo que se ajuste a los principios
de seguridad de software crtico. En esencia, se propone que los programas
estn escritos en un subconjunto "ms seguro" de C++.
High Integrity C++ (HICPP): Presentado por primera vez en 2003 por
Programming Research, la norma adopta el criterio de que se deben aplicar
restricciones sobre el lenguaje ISO C++ con el fin de limitar la flexibilidad que
ste permite. Este enfoque tiene el efecto de minimizar los problemas creados
por la diversidad de compiladores, los diferentes estilos de programacin y los
aspectos peligrosos y confusos del lenguaje.
En trminos generales, la eficacia de un estndar depende mucho de lo que se
pueda automatizar la deteccin de sus infracciones. La inspeccin de cdigo
manual ha demostrado ser ineficaz, costosa, lenta y propensa a errores
humanos.

130 / 136

Tipos habituales de normas


Tipo: Claridad del cdigo
Descripcin: Se trata de escribir cdigo claro, legible y poco confuso, evitando
construcciones que, siendo perfectamente vlidas, puedan hacer el cdigo difcil de leer.
Ejemplo: Relativas a la instruccin goto (6-6-1, 6-6-2), terminacin de bucles for (6-5-6)
Consejo: Sea flexible, ya que la claridad es una cuestin muy subjetiva. Fomente la
coherencia entre las y los diferentes desarrolladores.

Tipo: Simplicidad del cdigo


Descripcin: Mantener el cdigo lo ms simple posible, para minimizar los errores y hacer
ms sencillo el anlisis. Permite ayudar adems a reducir el coste de los tests.
Ejemplo: uso de continue (6-6-3), eliminacin de cdigo no usado (0-1-1, 0-1-2)
Consejo: Sea flexible, pero ten en cuenta que el incumplimiento de estas normas puede
afectar a los costes de las pruebas.

Tipo: Previsibilidad en la ejecucin del cdigo


Descripcin: Hacer previsible la ejecucin del software en todas las circunstancias,
eliminando las fuentes de ambigedad . Esto adems ayuda a la portabilidad.
Ejemplo: No recursividad (7-5-4), no memoria dinmica (18-4-1), no tipos dinmicos en el
constructor (12-1-1), divisin de enteros (1-0-3), una nica definicin (3-2-2, 3-2-3, 3-2-4)
Consejo: Evite el incumplimiento de las normas relativas a la previsibilidad del cdigo.

131 / 136

Tipos de normas
Tipo: Programacin Defensiva
Descripcin: Cuanto ms protegido est el software ante situaciones inesperadas, por
improbables que sean, mejor. Esto mejora adems la mantenibilidad del software.
Ejemplo: sentencias switch (6-4-3), no modificacin de contadores en los bucles for (6-53), no dar acceso a variables internas (9-3-2), tener en cuenta los errores (0-3-2)
Consejo: Sea moderadamente flexible, pero justifique bien las excepciones.

Tipo: Conformidad a normas


Descripcin: Siempre que sea posible, hay que intentar adecuarse a normas reconocidas.
Cumplir estas normas , adems, ayuda a mejorar la portabilidad.
Ejemplo: Uso de formatos estndar de coma flotante: ANSI/IEEE (0-4-3), compiladores
con interfaz comn (1-0-2), set de caracteres (2-2-1), secuencias de escape (2-13-1)
Consejo: Sea flexible, pero tenga en cuenta los posibles costes de transicin en el futuro.

Tipo: Proceso de desarrollo del software


Descripcin: Se refieren, no tanto al propio cdigo, sino al propio proceso mediante el
cual se desarrolla ste.
Ejemplo: Uso de mecanismos de anlisis esttico y dinmico (0-3-1)
Consejo: Evite incumplir estas normas, ya que seguirlas proporciona el mayor retorno de
la inversin

132 / 136

Las normas MISRA

MISRA significa "Motor Industry Software Reliability Association".


MISRA-C:1998 tena 127 normas, de las cuales 93 eran requisitos y 34
eran recomendaciones; las reglas estaban numeradas
secuencialemente desde el 1 al 127.
MISRA-C:2004 contiene 142 normas, de las cuales 122 son requisitos y
20 recomendaciones. Se dividen en 21 categoras temticas, desde
"Entorno" hasta "Fallos en tiempo de ejecucin" .
MISRA-C:2012 contiene 143 normas (el cumplimiento de las cuales es
analizable mediante el anlisis esttico del programa) y 16 directivas
(cuyo cumplimiento est ms abierto a la interpretacin , o se refiere a
cuestiones de proceso o de procedimiento), clasificadas por una parte
como "obligatorias", "necesarias" o "recomendables".
MISRA-C++:2008, como era de esperar, incluye un solapamiento
importante con MISRA C. Sin embargo, el estndar MISRA C++ incluye
228 normas, aproximadamente un 50% ms que el estndar MISRA C,
ya que comprende adems normas relativas a las funciones virtuales ,
manejo de excepciones , espacios de nombres, parmetros de
referencia, acceso a los datos de la clase encapsuladas, y otras facetas
especficas del lenguaje C++.
133 / 136

Preguntar es gratis!

Algunos enlaces

http://c.conclase.net/curso/
http://es.cppreference.com/w/cpp
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html
http://arco.esi.uclm.es/~david.villa/pensar_en_C++/
https://bitbucket.org/crysol_org/pensarenc/overview
http://www.learncpp.com/cpp-tutorial/
http://www.cplusplus.com/doc/tutorial/
http://www.zator.com/Cpp/
http://www.youtube.com/playlist?list=PL4A486BBFC5AD733B
http://mazyod.com/category/software-engineering/
http://www.cdsonline1.co.uk/EmailImages/mae/MAE09_speaker_presentations/MAE2009.ppt
http://assembly.ynh.io/ ( https://github.com/ynh/cpp-to-assembly )
http://msdn.microsoft.com/en-us/magazine/jj553512.aspx
http://www.open-std.org/jtc1/sc22/wg21/docs/ESC_San_Jose_98_401_paper.pdf
http://design-patterns-with-uml.blogspot.com.ar
http://en.wikipedia.org/wiki/Software_design_patterns
http://www.eventhelix.com/realtimemantra/patterns/

135 / 136

Licencia de este documento


Copyright 2014, Miriam Ruiz
This work is licensed under the Creative
Commons Attribution-Share Alike 3.0
(CC-by-sa 3.0) license. You can use, copy,
modify, merge, remix, distribute, display,
perform, sublicense and/or sale it freely under
the conditions defined in that license.
See http://creativecommons.org/licenses/by-sa/3.0/

Вам также может понравиться