Está en la página 1de 41

E M P R ES A XX X-

SO FT WA R E

Do cu me nt o de E s t án dar es
de Pr ogr am ac ió n

Fecha Creación 09-03-2007 AUTOR Proyecto EMPRESA XXX


Nombre Archivo DEP-EMPRESA XXX-V1
Versión 2.0
Estado Propuesto
Estándar de Programación y Estilos de Codificación en C++
Versión 2.0, Noviembre de 20XX

Proyecto EMPRESA XXX Software

Tabla de Contenidos

1. Introducción.................................................................................................................5
1.1 Convenciones Utilizadas..................................................................................................5
1.2 Actualizaciones Futuras...................................................................................................6
1.3 Referencias Básicas del Documento...................................................................................6
1.4 Ejemplos de Código.......................................................................................................6
1.5 Matriz de Cumplimiento para Desarrollo en C++...................................................................6
2. Recomendaciones Generales............................................................................................7
2.1 Cualquier modificación es permitida en mejora de la guía........................................................7
2.2 Violaciones de la reglas...................................................................................................7
3. Estructura de Proyectos en C++........................................................................................8
4. Reglas para el Control de Versiones...................................................................................9
4.1 Versionar código sin defectos...........................................................................................9
4.2 Estructura de comentarios de cambio..................................................................................9
4.3 Mantener la Rama Principal Incorrupta...............................................................................9
4.4 Asociar Cambios en las Ramas con Software de Control de Tareas. ...........................................9
4.5 Guardar los cambios frecuentemente..................................................................................9
4.6 Realizar Merge antes de todo Update..................................................................................9
4.7 Commit.....................................................................................................................10
4.8 Backups.....................................................................................................................10
4.9 Restores.....................................................................................................................10
5. Definición de Reglas Generales para el nombramiento de código C++.....................................11
5.1 Estructuración de nombres significativos...........................................................................11
5.2 Estructuración de nombres descriptivos.............................................................................11
5.3 Inicialización de variables..............................................................................................11
5.4 Variables genéricas deben usar el mismo nombre que el tipo..................................................12
5.5 Variables no genéricas deben tener como nombre el rol y tipo................................................12
5.6 Variables deben tener el mínimo alcance posible.................................................................12
5.7 Conversión de variables debe ser realizada explícitamente.....................................................12
5.8 Prueba implícita con 0 deberá usarse únicamente para variables boolean...................................12
5.9 Variables globales deberán usar el operador “::”..................................................................12
5.10 Toda variable deberá tener máximo 20 caracteres de longitud. ................................................12
5.11 Variables que representen colecciones de elementos debe escribirse en plural.............................13
5.12 Toda variable de GUI deberá tener como sufijación el nombre del tipo de componente. ................13
5.13 Toda variable que representa valores numéricos deberá incluir el prefijo “n” seguido del nombre de la
variable en mayúscula..................................................................................................13
5.14 Todo valor de punto flotante debe tener al menos un dígito antes del punto y/o un decimal. ...........13
5.15 Usar “NULL” en lugar de “0”, por ser un estándar de C aunque en C++ ya está obsoleto. ..............13
5.16 Evitar el uso de goto en lo posible....................................................................................13
5.17 Todo iterador deberá ser declarado con variables especiales como “i”, “j”, “k”. ..........................14

2
5.18 El prefijo “is” deberá ser usado para variables o métodos de tipo boolean. .................................14
5.19 Sugerencias sobre el uso de abreviaturas............................................................................14
5.20 El uso de palabras como Compute y Find deberán emplearse según su definición. .......................15
5.21 Uso de abreviaciones y/o acrónimos como nombre deberá ser escrito utilizando el estándar 5.1 ......15
5.22 El término “initialize” debe ser usado según su concepción, evitando en lo posible el uso de
abreviaturas como “init” o derivados como “load”...............................................................15
5.23 Enumeraciones............................................................................................................16
5.24 Excepciones...............................................................................................................16
5.25 Espacios de nombre (namespaces)...................................................................................16
6. Comentarios y Estilos...................................................................................................18
6.1 Comentarios...............................................................................................................18
6.1.1 En los encabezados de archivos.......................................................................................18
6.1.2 En las declaraciones de código........................................................................................18
6.1.3 En una línea de código..................................................................................................19
6.2 Estilos.......................................................................................................................19
6.2.1 Identación debe tener 2 espacios en blanco.........................................................................19
6.2.2 Espacios en blanco.......................................................................................................19
6.2.3 Construcciones “if-else” deben tener la siguiente estructuración..............................................20
6.2.4 Construcciones “switch-case” deben tener la siguiente estructuración .......................................20
6.2.5 Construcciones “for” y “while” deben tener la siguiente estructuración .....................................20
6.2.6 Unidades lógicas de código debe estar separadas por una línea en blanco..................................21
6.2.7 Construcciones “try-catch” deben tener la siguiente estructuración..........................................21
7. Control y Repetición....................................................................................................22
7.1 Evitar el uso de expresiones condicionales complejas...........................................................22
7.2 Construcción “if” con flujo regular de ejecución y “else” con flujo de excepción .........................22
7.3 Bloque de instrucción de condicionales debe ir en una línea separada.......................................22
7.4 Evitar la asignación de valores en condicionales..................................................................22
7.5 Sólo incluir variables de iteración en construcciones “for”.....................................................22
7.6 Variables de control deben ser inicializadas inmediatamente antes de ser usadas .........................23
7.7 Evitar el uso de “do..while”, usar construcciones basadas en “while” o “for” ..............................23
7.8 Evitar el uso de instrucciones “while (1)” y “for(;;)” ya que no son muy legibles .........................23
8. Archivos...................................................................................................................24
8.1 Extensiones................................................................................................................24
8.2 Incluir guards en los archivos de cabecera..........................................................................24
8.3 Orden y agrupamiento de las instrucciones “include”............................................................25
8.4 Contenido..................................................................................................................25
8.5 Evitar el uso de TAB y page break...................................................................................25
9. Declaración de Clases y Estructuras.................................................................................26
9.1 Organización de una clase o estructura (ref: Hight Integrity Rule. 3.1.1)....................................26
9.2 Restringir el uso de Herencia Múltiple..............................................................................26
9.3 Declaración de miembros...............................................................................................26
9.4 Constructores y Destructores..........................................................................................27
9.5 Utilizar Deep Copy para duplicar objetos (ref: High Integrity CPP Rule 3.1.3, 3.1.4,
3.1.5).....................................................................................................................28
9.6 Uso de Const..............................................................................................................28
9.7 Utilizar en métodos con valor en lugar de constantes...........................................................29
9.8 Reutilización el Comportamiento.....................................................................................30
9.9 Macros debe ser creadas para simplificar la escritura de código y/o reusar comportamiento genérico.
...............................................................................................................................31
9.10 Aserciones.................................................................................................................31
10................................................................................................................................................31
11. Patrones de Diseño......................................................................................................32
11.1 Patrón Observer...........................................................................................................32
11.2 Patrón Fachada............................................................................................................33

3
11.3 Patrón Abstract Factory.................................................................................................34
11.4 Patrón Factory Method..................................................................................................36
11.5 Patrón Singleton..........................................................................................................37
Ejemplo:.....................................................................................................................................37
11.6 Patrón Listener............................................................................................................38
11.7 Patrón Estrategy..........................................................................................................38
11.8 Patrón Proxy...............................................................................................................39
12. Referencias................................................................................................................41

4
Estándar de Programación y Estilos de Codificación en C++
Versión 2.0, Noviembre de 20XX

Proyecto EMPRESA XXX Software

1. Introducción

El presente documento detalla las recomendaciones más comunes para las convenciones
de nombre usadas en códigos de C++. Estas recomendaciones están basadas en
estándares establecidos recolectados de un gran número de fuentes, experiencia individual,
requerimientos locales, necesidades, como también sugerencias recibidas.

Este documento trata de ser más una guía para la programación en C++ que un documento
de recomendaciones técnicas.

Las IDE’s (entornos integrados de desarrollo) permiten al programador facilitar la lectura del
código mejorando la visibilidad con colores, formato automático, etc. El programador no
debería confiase en estas características ya que la visibilidad (comprensión) del código
debería estar por encima de las ayudas que nos pueda brindar un poderoso IDE. La idea es
maximizar la comprensión y lectura del código independientemente del IDE que se utilice.

1.1 Convenciones Utilizadas

Regla: Recomendación que deberá seguirse obligatoriamente al escribir


código en C++. Puede o no incluir ejemplos.

Guía: Conjunto de recomendaciones basadas en estándares, normas y


experiencias que facilitan la legibilidad de código. Generalmente
presenta ejemplos.

Justificación: Párrafo que explica brevemente el uso de una regla o


guía.

Excepción: Párrafo que explica los casos en donde la regla o guía no


cumple.

Vea También: Sección que lista las referencias a reglas o guías que
son relevantes a la regla o guía actual.

5
Referencia: Esta sección lista las fuentes de las referencias relevantes.

Palabra clave: Toda palabra clave ya sea un prefijo, sufijo o del


lenguaje será encerrada entre apóstrofes en el texto.

1.2 Actualizaciones Futuras

El documento debe estar sujeto a revisiones y en caso lo amerite a actualizaciones


periódicas que incluyan nuevas semánticas, estilos y características de C++. Cada
actualización generará un incremento en el número de versión cuando el documento
incluya un conjunto de cambios que conlleven a su restructuración, en caso contrario
se realizará sólo un incremento de la revisión.

1.3 Referencias Básicas del Documento

High·Integrity C++ Coding Standard Manual v.2.4, Diciembre del 2006 © THE
PROGRAMMING RESEARCH GROUP.

1.4 Ejemplos de Código

Todos los ejemplos de código estarán contenidos dentro de recuadros con fondo
gris claro y tipo de letra Courier New, 10 pts. Por ejemplo:
class ProcessTopic
{
string m_processName;
int m_priority;
int m_cpuUsage;
string m_nodeName;
}

1.5 Matriz de Cumplimiento para Desarrollo en C++

La presente guía está orientada a los siguientes aspectos particulares de desarrollo


para el proyecto EMPRESA XXX:

Característica Descripción
Descripción del Desarrollo Proyecto EMPRESA XXX
Versión del Compilador GNU compiler for C++ versión 4.3
Switches del Compilador 0-3
Tipo de Hardware Hardware para gabinetes G1, G2 y G3.
Sistema Operativo Ubunto 9.10
- DDS Open Splice v.4.x
Librería de Terceras Partes
- QT v. 4.5

6
2. Recomendaciones Generales

2.1 Cualquier modificación es permitida en mejora de la guía

Las recomendaciones de todo tipo están sujetas a variaciones siempre y cuando se


produzcan contribuciones técnicas o mejoras en legibilidad en el documento.

2.2 Violaciones de la reglas

Programadores experimentados en C++ pueden adoptar reglas particulares cuyo uso


sea mejor que las reglas en curso. Para ello se deberá aprobar su uso por el comité
técnico del proyecto, quién deberá sugerir modificaciones a la presente guía, según
se establece en la recomendación 2.1.

7
3. Estructura de Proyectos en C++

Antes de trabajar con un nuevo proyecto se deberá indicar el Workspace donde este
estará contenido, en este caso se utiliza el Workspace EMPRESA XXX. Al añadir un
nuevo proyecto, ese se deberá trabajar con una instancia de la IDE de Eclipse, es decir
si se trabaja con dos proyectos a la vez se tendrán dos ventanas de la IDE una por cada
proyecto.

Cualquier proyecto nuevo se deberá estructurar con las siguientes carpetas, según se
muestra a continuación:

CARPETA PROPÓSITO
Módulo del proyecto EMPRESA XXX. Corresponde al
Proyecto
namespace
Carpeta de código fuente. Deben estar todos los archivos
source
que se producen a mano
Common Carpeta con cabeceras comunes.
Common.h,
Debug.h, Cabeceras de uso obligatorio.
Debug.cpp
Singleton.hpp,
Cabeceras de definición de patrones de programación
Uncopyable.hpp
Cabecera para definir página de documentación del
Documentacion.h
módulo
CommDDS Carpeta para el XML de entidades de DDS
Carpeta con el código generado a partir del XML de las
Autogen
entidades de DDS
<Paquete> Carpeta correspondiente al paquete y namespace.
Qacproject Carpeta con configuración del proyecto de QACPP
Output Salida del QACPP
personalities Configuración de compilador y entorno.
<Proyecto>.prj Define proyecto de QACPP
library (opcional) Librerías de terceros

Importante

Si bien es cierto que la carpeta Library es opcional, es importante considerar una


estructura uniforme en caso de estar presente en el proyecto. Por ejemplo si el
proyecto utiliza las APIs de OSIRIS, se deberá crear una carpeta con ese nombre.

8
4. Reglas para el Control de Versiones

4.1 Versionar código sin defectos

Todo código se dará por terminado siempre que esté exento de errores de
compilación deberá ser versionados.

4.2 Estructura de comentarios de cambio

Los comentarios deberán ser estructurados del siguiente modo:

Usuario, fecha {dd/mm/yyyy}


Proyecto.Módulo
Clase
Descripción del Cambio

Ejemplo

aibanez, 16/12/2009
EMPRESA XXX.Mapping
XmlTokenizer
Corrección de errores en el método Parse.
XmlReader
Se sobrecargó el método Load para recibir un array de bytes.

4.3 Mantener la Rama Principal Incorrupta.

La rama principal tiene una estructura que debe regir (ver cap. 3), no crear
directorios ni elementos que ya no sirvan.

4.4 Asociar Cambios en las Ramas con Software de Control de Tareas.

Asociar la rama con una con una tarea en la herramienta de control de tareas
(Bugzilla, Mantis, Jira, etc.), esto es útil para mantener un seguimiento de avances
diários.

4.5 Guardar los cambios frecuentemente

Los cambios a nivel de la rama principal tardan más en guardarse y por lo tanto
deberán hacerse cada 20 minutos, mientras que los cambios en las ramas
secundarias se realizarán cada 5 minutos.

4.6 Realizar Merge antes de todo Update

Se deberá combinar los cambios de la copia local con los del servidor, de tal manera
que se tenga una versión unificada de los mismos. En caso de no existir la copia local
esta será una imagen de la existente en el servidor.

9
4.7 Commit

Cuando la copia local actualice la copia del servidor deberá siempre contar con un
comentario que detalle los cambios producidos en las clases y métodos.

4.8 Backups

Actualmente se cuenta con un almacenamiento de espejo en el servidor para los


backups, por lo que es recomendable además realizar backups mensuales en
dispositivos externos como CDs. Se recomienda que todos los usuarios concurrentes
realicen commit del código luego de cada modificación (ver 4.5).

4.9 Restores

Ante cualquier falla se deberá restaurar el último backup y realizar commit desde los
terminales al repositorio con la finalidad de actualizar cambios progresivos que no
estarían presentes en la última copia realizada.

10
5. Definición de Reglas Generales para el nombramiento de código C++

5.1 Estructuración de nombres significativos

Todo nombre significativo deberá ser escrito en inglés americano (‘A’-‘Z’); sin incluir
números ni caracteres especiales, en donde la primera letra de cada palabra deberá
ser mayúscula. Los monosílabos serán excluidos de la nomenclatura.

La regla rige para elementos del tipo espacios de nombre, clase y elementos que
requieren un mayor énfasis en el código dada su importancia. Para el caso de
estructuras y enumeraciones se usará un prefijo correspondiente.

Ejemplo

class Node
{
public:
void setStatus(…);
}

5.2 Estructuración de nombres descriptivos

Todo nombre descriptivo deberá ser escrito en minúscula e inglés (‘A’-‘Z’) sin incluir
números ni caracteres especiales. Si el nombre estuviera formado por dos o más
palabras, el primer carácter a partir de la segunda palabra será en mayúscula, por
ejemplo: initialize, terminate, stopRecording, startRecording, etc. Esta nomenclatura
rige tanto para operaciones miembro, campos de clases, variables en general y
parámetros.

Ejemplo

class Node
{
public:
void initialize();
void setStatus(…);
}

5.3 Inicialización de variables

Toda variable deberá usar inicialización directa en lugar de copiar su inicialización a


fin de evitar la copia del objeto, por ejemplo: fileName, localSetting, isRegistered,
etc.

Importante

Aunque algunos compiladores pueden optimizar la construcción del objeto tratando la


copia de inicialización como una inicialización directa. Sin embargo es una buena
práctica implementar este mecanismo explícitamente.

11
Ejemplo

class Node
{
public:
Node():m_nodeStatus(-1) {}
private:
int m_nodeStatus;
}

5.4 Variables genéricas deben usar el mismo nombre que el tipo

Ejemplo:

void setTopic(Topic topic) ///< NO: void setTopic(Topic value)

5.5 Variables no genéricas deben tener como nombre el rol y tipo

Ejemplo:

String m_fileName /// < A nivel de clase


String systemFileName /// < A nivel de toda la aplicación

5.6 Variables deben tener el mínimo alcance posible

Las operaciones realizadas sobre variables de poco alcance son fáciles de controlar.

5.7 Conversión de variables debe ser realizada explícitamente

Ejemplo:

m_roi = static_cast<float>(50);

5.8 Prueba implícita con 0 deberá usarse únicamente para variables boolean

Ejemplo:

if (nLines != 0) ///< NOT: if (nLines)


if (value != 0.0) ///< NOT: if (value)

5.9 Variables globales deberán usar el operador “::”

Ejemplo:

::mainWindow.open();
::applicationContext.getName();

5.10 Toda variable deberá tener máximo 20 caracteres de longitud.

Ejemplo:

String customerFullName /// < NO: customerFirstAndLastName


int totalQuantity /// < NO: totalQty

12
Las variables con mayor alcance deberán tener nombres más largos. Véanse también
los ejemplos de la sección 5.5.

5.11 Variables que representen colecciones de elementos debe escribirse en


plural.

Ejemplo:

Order[] m_orders; /// < a nivel de miembro de clase


FileHandle[] logFiles; /// < a nivel de módulo
FileHandle[] systemFiles; /// < a nivel de la aplicación

5.12 Toda variable de GUI deberá tener como sufijación el nombre del tipo de
componente.

Ejemplo:

okButton, exitMenu, firstNameText, titleLabel, yesToggle,


openFileDialog, leftScrollbar, customerWindow, mainStatusbar

5.13 Toda variable que representa valores numéricos deberá incluir el prefijo
“n” seguido del nombre de la variable en mayúscula.

Ejemplo:

int m_nFiles; ///< A nivel de clases


int nFiles; ///< A nivel de aplicación

5.14 Todo valor de punto flotante debe tener al menos un dígito antes del
punto y/o un decimal.

Ejemplo:

///< incorrecto
float factor = 4;
float tax = .72; /// < menos legible

///< correcto
float factor = 4.0;
float tax = 0.72; /// < más legible

5.15 Usar “NULL” en lugar de “0”, por ser un estándar de C aunque en C++ ya
está obsoleto.

Ejemplo:

///< incorrecto
if (customer == 0)
customer(“Juan Pérez”);

///< correcto
if (customer == NULL)
customer(“Juan Pérez”);

5.16 Evitar el uso de goto en lo posible.

13
El uso de goto viola la estructuración de código, sólo se permite su uso en
anidamientos muy profundos

5.17 Todo iterador deberá ser declarado con variables especiales como “i”, “j”,
“k”.

Las variables “j” y “k” deberán ser utilizadas para bucles anidados solamente.

Ejemplo:

for (int i = 0; i < nFiles); i++)


{ ... }
for (vector<MyClass>::iterator i = list.begin(); i != list.end(); i++)
{ ... }

5.18 El prefijo “is” deberá ser usado para variables o métodos de tipo boolean.

El uso del prefijo “is” se da a nivel de todo ámbito por lo que se deberá evitar el uso
de la palabra “no/not” como parte del nombre.

Ejemplo con variables

bool m_isActive; ///< A nivel de clases, evitar m_isNotActive


bool isClosed; ///< A nivel de aplicación

Ejemplo con Métodos

bool isAuthenticated(String login, String password);

Algunas variaciones pueden incluir el uso de prefijos como “can”, “has” o “should”.

Ejemplo Alternativos

bool hasSubordinates (Employee employee);


bool canBeRetired (Employee employee);
bool shoulBeBoss (Employee employee);

5.19 Sugerencias sobre el uso de abreviaturas.

Tanto acciones (verbos en infinitivo) como sustantivos no pueden ser abreviados.

Ejemplo de frases sin abreviar:

Usar en lugar de
command cmd
copy cpy
point pt
component cmp
initialize init

Las frases de dominio específico por lo general tienen un significado propio como
abreviación/acrónimo, por lo tanto conviene mejor abreviar que usar la frase
competa.

Ejemplo de frases abreviadas:

Usar en lugar de
xml ExtensibleMarkupLanguage
roi ReturnOfInvesment

14
5.20 El uso de palabras como Compute y Find deberán emplearse según su
definición.

Ejemplo:

class Customer{
public:
float computeAnualOrders(int year) {}
Order[] findAnualOrders(int year): findAnualOrders(year, year) {}
Order[] findAnualOrders(int fromYear, int toYear) {}
}

5.21 Uso de abreviaciones y/o acrónimos como nombre deberá ser escrito
utilizando el estándar 5.1

Ejemplo:

exportHtmlSource(); ///< NO: exportHTMLSource();


openDvdPlayer(); ///< NO: openDVDPlayer();

5.22 El término “initialize” debe ser usado según su concepción, evitando en


lo posible el uso de abreviaturas como “init” o derivados como “load”.

Ejemplo:

class Customer
{
public:
Order[] findAnualOrders(int fromYear, int toYear)
{
initializeOrders();

return m_orders;
}
protected:
void initializeOrders();
{
m_nOrders(0);
m_orders = new Order[]{};
}
private:
Order[] m_orders;
int m_nOrders;
}

15
5.23 Enumeraciones

Nombres: Escritos en plural con la primera letra de cada palabra en mayúscula. No


se usa ningún separador entre palabras.

Constantes: Escritos en singular y mayúscula. Se usa el separador “_” entre


palabras.

Ejemplo:

enum Color {
COLOR_RED = 0x10A5, ///< Valor para Rojo;
COLOR_GREEN = 0x11B2, ///< Valor para Verde;
COLOR_BLUE = 0x12C7 ///< Valor para Azul;
};

Para referenciar a las constantes se deberá utilizar la prefijación del nombre de la


enumeración.
int m_defaultColor = Color::COLOR_BLUE;

5.24 Excepciones

Toda clase de este tipo heredará de la clase Exception y deberá ser escrita
<NombreClase>Exception

Ejemplo:

class NullReferenceException: public Exception {


. . .
};

5.25 Espacios de nombre (namespaces)

Los espacios de nombre se utilizan para agrupar estructuralmente un conjunto de


declaraciones, variables, constantes, funciones, clases y estructuras relacionadas a
una determinada funcionalidad como por ejemplo un subsistema. El nombre
utilizado para cualquier espacio deberá estar regido por el estándar 5.1.

Namespace de un Nivel

namespace {Nombre del Namespace}


{
... ///< declaraciones y/o variables, clases, ...
}

16
Namespace de Múltiples Niveles

namespace {Nombre del Namespace1}


{
... ///< declaraciones y/o variables, clases, ...

namespace {Nombre del Namespace2}


{
... ///< declaraciones y/o variables, clases, ...
...
namespace {Nombre del NamespaceN}
{
... ///< declaraciones y/o variables, clases, ...

}
}

Ejemplo

Namespace de un Nivel
namespace Utilities
{
... ///< declaraciones y/o variables, clases, ...
}

Namespace de Múltiples Niveles


namespace EMPRESA XXX
{
namespace Utilities
{
... ///< declaraciones y/o variables, clases, ...
}
}

17
6. Comentarios y Estilos

6.1 Comentarios

Deberán ser estructurados para seguir las convenciones establecidas tanto por la
herramienta de documentación de código Doxygen como los estándares recomendados
por la herramienta QACPP. Los comentarios según su categoría pueden ir:

6.1.1 En los encabezados de archivos

Todo archivo de código deberá incluir un encabezado de la forma:

///
/// EMPRESA XXX PROJECT
/// \File : archivo.h/archivo.hpp/archivo.cpp
/// \Version : nroVersión.nroRevisión
/// \Author : Nombre del usuario
/// \Date : dd/mm/aaaa
///

Un cambio significativo incrementará el número de versión, en cualquier otro


cambio incrementará el número de revisión. Si la revisión es 9 se generará un
incremento en el número de versión con número de revisión 0.

Ejemplo:
///
/// EMPRESA XXX PROJECT
/// \File : Dictionary.hpp
/// \Version : 1.0
/// \Author : aibanez
/// \Date : 16/12/2009
///

6.1.2 En las declaraciones de código

Antes de la declaración de una clase, estructura, unión o enumeración u


operación, siendo opcional el uso de return si la operación devuelve un valor:
/// \brief Primera línea de descripción
/// Segunda línea de descripción
/// Tercera línea de descripción
/// y así sucesivamente…

/// \return {descripción del tipo de retorno}

Ejemplo:
class Dictionary {
/// \brief Serializa el diccionario a XML

/// Este método exporta los keys como elementos XML,


/// según el orden de definición en el diccionario.
/// Los valores del tipo XmlElemento serán anidados.

/// \return retorna 0 si tuvo éxito sino -1.


int serialize(String filename,///< Nombre del archivo
bool overwrite ///< sobrescribir el archivo
);

18
6.1.3 En una línea de código
Son escritas a la derecha de cualquier línea de código y se usa para describirla
brevemente.
<línea-código> ///< breve desceipción.

Ejemplo:

protected:
T* m_ptr; ///< Puntero al objeto de la clase.
6.2 Estilos

Serán establecidos para cualquier estructuración de código en C++, siguiendo las


siguientes convenciones:

6.2.1 Identación debe tener 2 espacios en blanco


Ejemplo:

class Customer
{
public:
void register(); ///< 2 espacios a la derecha de public.
private: ///< 2 espacios a la derecha de la llave de apertura.
Order [] m_orders; ///< 2 espacios a la derecha de private.
}

6.2.2 Espacios en blanco


Las identaciones deberán tener dos espacios en blanco.

Los siguientes operadores preceden de un espacio en blanco:

[]: corchetes, (): paréntesis, ,: coma.

Los siguientes operadores preceden y proceden de un espacio en blanco:

+, -, *, /, \: matemáticos, <, >, ==, !=: comparativos, &&, || : lógicos,

<<, >>: rotación de bits.

Ejemplo en declaración de clases:

class Customer
{
private: ///< 2 espacios a la derecha.
Order [] m_orders; ///< 1 espacio antes y después del corchete.
protected:
void initializeOrders (); ///< 1 espacio antes del paréntesis
}

Ejemplo en implementación de clases:

Customer::initializeOrders () ///< 1 espacios antes del paréntesis


{
m_orders = new Order [] {}; ///< 2 espacios antes y después
m_nOrders (0); ///< de los operadores
}

19
6.2.3 Construcciones “if-else” deben tener la siguiente estructuración
///< Con bloque de instrucciones simple
if (condición)
Instrucciones-1-Línea...
else [if (condición-alternativa)]
Instrucciones-1-Línea...
else
Instrucciones-1-Línea...

///< Con bloque de instrucciones de múltiples líneas


if (condición){
Instrucciones-Multiples-Líneas...
}
else [if (condición-alternativa)]{
Instrucciones-Multiples-Líneas...
}
else {
Instrucciones-Multiples-Líneas...
}

6.2.4 Construcciones “switch-case” deben tener la siguiente estructuración

Cada instrucción case debe ir identada 2 espacios a la derecha del switch, antes
del carácter “:” deberá ir un espacio en blanco.

La palabra fallthrought indica que la instrucción al terminar sale del bloque


“switch-case” sin necesidad de usar break.

Luego de cada instrucción case deberá ir una línea en blanco.

switch (condition) {
case ABC :
statements;
///< Fallthrough

case DEF :
statements;
break;

case XYZ :
statements;
break;

default :
statements;
break;
}

6.2.5 Construcciones “for” y “while” deben tener la siguiente estructuración


///< Con bloque de instrucciones simple
for (inicialización; condición; incremento)
Instrucciones-1-Línea...

///< Con bloque de instrucciones de múltiples líneas


for (inicialización; condición; incremento)
{
Instrucciones-Multiples-Líneas...
}

///< Con bloque de instrucciones simple


while (condición)
Instrucciones-1-Línea...
///< Con bloque de instrucciones de múltiples líneas

20
while (condición)
{
Instrucciones-Multiples-Líneas...
incremento;
}
6.2.6 Unidades lógicas de código debe estar separadas por una línea en blanco
Matrix4x4 matrix = new Matrix4x4();

double cosAngle = Math.cos(angle);


double sinAngle = Math.sin(angle);

matrix.setElement(1, 1, cosAngle);
matrix.setElement(1, 2, sinAngle);
matrix.setElement(2, 1, -sinAngle);
matrix.setElement(2, 2, cosAngle);

multiply(matrix);

6.2.7 Construcciones “try-catch” deben tener la siguiente estructuración


Cada instrucción dentro del bloque “try” ó “catch” deberá tener dos espacios en
blanco a la derecha.
try {
statements;
}
catch (Exception& exception) {
statements;
}

21
7. Control y Repetición

7.1 Evitar el uso de expresiones condicionales complejas

Utilizar variables booleanas para factorizar expresiones complejas.

Ejemplo:

bool isFinished = (elementNo < 0) || (elementNo > maxElement);


bool isRepeatedEntry = elementNo == lastElement;
if (isFinished || isRepeatedEntry) { : }

///< NO: if ((elementNo < 0) || (elementNo > maxElement)||


elementNo == lastElement) { : }

7.2 Construcción “if” con flujo regular de ejecución y “else” con flujo de excepción

Provee un resultado más legible y fácil de mantener.

Ejemplo:

bool isOk = readFile (fileName);


if (isOk) { : }
else { : }

7.3 Bloque de instrucción de condicionales debe ir en una línea separada


Ejemplo:

bool isOk = readFile (fileName);


if (isOk)
copyFile(fileName, newFileName);

7.4 Evitar la asignación de valores en condicionales

Ejemplo:

///< Incorrecto
if ((cust = custList.FindByCode(“033557437”)) != NULL)
printCustomer(cust);

///< Correcto
Customer cust = custList.FindByCode(“033557437”);
if (cust != NULL)
printCustomer(cust);

7.5 Sólo incluir variables de iteración en construcciones “for”

Permite tener un código más legible y fácil de mantener.

Ejemplo:

///< Incorrecto
for (i = 0, sum = 0; i < 100; i++)
sum += value[i];

///< Correcto
sum = 0;
for (i = 0; i < 100; i++)
sum += value[i];

22
7.6 Variables de control deben ser inicializadas inmediatamente antes de ser usadas
Ejemplo:

///< Incorrecto
bool isRegistered = false;
. . .
if (!isRegistered)
register();

///< Correcto
bool isRegistered = false;
if (!isRegistered)
register();

7.7 Evitar el uso de “do..while”, usar construcciones basadas en “while” o “for”


Para entender este tipo de construcciones el desarrollador deberá leer todo el
bloque de código, dificultando la legibilidad y comprensión.

7.8 Evitar el uso de instrucciones “while (1)” y “for(;;)” ya que no son muy legibles
Se deberá usar como alternativa “while(true)” que resulta mucho más
comprensible y fácil de mantener.

23
8. Archivos

8.1 Extensiones

Todo código deberá componerse de un par de archivos1.

Declaración: Utilizan extensión “.h” y deben referenciar únicamente a otras


declaraciones.

Implementación: Utilizan extensión “.cpp”, “.cc” ó “.c” y deben referenciar a sus


respectivas declaraciones.

Ejemplo de cabecera:

/// \brief Customer.hpp


class Customer {
public:
Customer();
void register();
};

Ejemplo de implementación:

#include “customer.hpp”
/// \brief Customer.cpp
Customer::Customer()
{
}
void Customer::register()
{
. . .
}

8.2 Incluir guards en los archivos de cabecera

#ifndef MODULO_NOMBRECLASE_H
#define MODULO_NOMBRECLASE_H

class <NombreClase>
{
. . .
}

#endif ///< MODULO_NOMBRECLASE_H

Ejemplo de cabecera:

#ifndef SALES_CUSTOMER_H
#define SALES_CUSTOMER_H
class Customer {
public:
Customer();
void register();
}
#endif ///< SALES_CUSTOMER_H

1
Se recomienda utilizar aquellas extensiones que se muestran resaltadas en negrita.

24
8.3 Orden y agrupamiento de las instrucciones “include”

Las instrucciones include deben referirse primero a archivos de más bajo nivel para
el sistema. Luego de cada grupo dejar una línea en blanco.

Las rutas siempre deben ser relativas para todos los archivos.

Ejemplo:

#include <fstream>
#include <iomanip>
#include <qt/qbutton.h>
#include <qt/qtextfield.h>
#include "EMPRESA XXX/common/ui/PropertiesDialog.h"
#include "EMPRESA XXX/common/ui/MainWindow.h"

8.4 Contenido

El ancho de columnas por línea de código deberá estar sujeto a 80 columnas por
compatibilidad con la mayoría de editores de código, impresoras, emuladores y
depuradores de código. Así mismo para mejorar la legibilidad de código.

Se recomienda:

1. Iniciar una nueva línea si existe un carácter “;” al final de la línea previa.

2. Luego de un operador al llegar cerca de la 80va columna.

3. Iniciar una nueva línea alineada por la izquierda al mismo nivel de la línea
previa.

8.5 Evitar el uso de TAB y page break

Estos caracteres originan problemas con en un entorno de multiprogramación con


editores diversos, emuladores y depuradores.

25
9. Declaración de Clases y Estructuras

9.1 Organización de una clase o estructura (ref: Hight Integrity Rule. 3.1.1)

Toda clase o estructura debe ser escrita en orden decreciente de su nivel de


visibilidad comenzando por la mayor visibilidad hacia la menor en el siguiente orden:

- public: Indica que el miembro es visible sin restricciones.


- protected: Indica que el miembro de la clase sólo puede ser accedido por las
operaciones miembro de la misma clase y todos sus descendientes.
- private (predeterminado): Indica que el miembro sólo puede ser accedido por
las operaciones miembro de la misma clase que lo declara.

Ejemplo

class/struct MyEntity
{
public: ///< 1°
// ...
protected: ///< 2°
// ...
private: ///< 3°
// ...
}

9.2 Restringir el uso de Herencia Múltiple

Deberá evitarse en lo posible la herencia múltiple, en caso que sea sumamente


requerido se recomienda evitar la herencia en rombo.

Ejemplo

class A
{
}

class B: A
{
}

class C: B, A ///< NO REALIZAR


{
}

class C1: B ///< OK


{
}

9.3 Declaración de miembros

Todo nombre de clase estará regido obligatoriamente por la estándar 5.1. Además
los miembros de una clase tendrán la siguiente convención de nombres:

o Constructores y Destructores : Deberán ser declarados explícitamente a


fin de controlar mejor la asignación y liberación de recursos.

o Variables Miembro o Campos: Utiliza un prefijo conformado por la letra


‘m’ seguido de un carácter de subrayado ‘_’. El nombre estará regido por

26
el estándar 5.2, además del estándar 5.3 en caso de requerir
inicialización previa, por ejemplo para variables miembro con:

 Nombre Simple: m_priority.

 Nombre Compuesto: m_nodeStatus.

 Valor de Inicialización: m_isSynchronized (1).

Ref: High Integrity CPP Rule 3.1.2

Toda variable miembro que derive de la clase SmartPtr<Tipo>,


deberá tener la prefijación “ptr” luego del carácter de subrayado
pero antes del nombre, por ejemplo:

o Operaciones Miembro: Su nomenclatura estarán regidas por el estándar


5.2, y debe evitar tener el nombre del objeto o tipo de clase. Toda
operación puede ser de tres tipos: set, get, action.

 get/set: Deberá utilizarse para operaciones que modifican


atributos de las clases, por ejemplo: getStatus, setStatus, etc.
No usar getCustomerStatus, setCustomerStatus.

 Action: Operación que desencadena un procesamiento


específico, por ejemplo: startSynchronization,
stopSynchronization, etc.

 Parámetros: Todo nombre de parámetro deberá seguir la


convención del estándar 5.2.

Ejemplo

namespace EMPRESA XXX


{
namespace Utilities {
template <class T>
class Stack {
public:
Stack(int size = 10){...}
~Stack(){...}
int push(const T& newItem){...}
int pop(T&){...}
int isEmpty()const {...}
private:
int m_size, m_top; T* m_ptrStack;
} ;
}
}

9.4 Constructores y Destructores

La invocación al constructor del padre deberá respetar la jerarquía de herencia,


comenzando por el constructor de la clase de primer nivel y así sucesivamente hasta
llegar a los miembros de la clase actual.

Todo destructor deberá ser virtual en un escenario de herencia 2.

27
Ejemplo

class Parent {};


class BaseShip: public Parent {};
class VirtualShip: public BaseShip{
public:
VirtualShip(): Parent(), BaseShip()
m_shipName(“No Name”),
m_ShipNo(0)
{
m_ptrCoordinate =
SmartPtr<Coordinate>(new Coordinate);
}
virtual ~VirtualShip() {}
private:
String m_shipName; ///< Nombre del barco.
unsigned int m_ShipNo; ///< Nro del barco.
SmartPtr<Coordinate> * m_ptrCoordinate;
};

9.5 Utilizar Deep Copy para duplicar objetos (ref: High Integrity CPP Rule 3.1.3,
3.1.4, 3.1.5)

Toda copia de objeto deberá realizarse sobrecargando el operador “=” y utilizando


un método para realizar la copia por separado. El primer paso es liberar todos los
recursos para luego copiar el objeto.

Ejemplo

class MyClass
{
public:
MyClass& operator=( const MyClass& objRef )
{
if(m_intRef != NULL)
delete m_intRef;
swap( temp ); /// < non-throwing
return *this;
{
int getSize()
{ Return m_size;}
private:
int * m_intRef;
int m_size;
void swap( MyClass& objRef ) throw ();
};

9.6 Uso de Const

El uso de const se puede dar de manera individual o conjunta de acuerdo a los


siguientes tipos:

o “Const” en Parámetros de Operaciones de Clase: Utilizar siempre


parámetros const para objetos excepto para los punteros inteligentes.
Sintaxis:
<nombre-de-función>(const <nombre-de-parámetro>[,…])

28
o “Const” en Operaciones Miembro: Utilizar este modificador si la
operación es de sólo lectura. (Ref. High Integrity CPP Rule 3.1.8)
Sintaxis:
<nombre-de-función> const;

o “Const” Globales: Su uso debe estar restringido.


Sintaxis:
const <NOMBRE-CONSTANTE = valor >;

Ejemplo

Const en parámetros de clase.


class myClass {
int m_k; /// < declara k constante (private)
int m_x; /// < declara x no constante (private)
public:
/// < declara una referencia a MyClass read only
int f1(const myClass & instance)
{
return (instance.m_x - instance.m_k);
}
...

};

Const en operaciones miembro


class MyClass {
int m_x; /// < Private por defecto
public:
int func(int i) const
{
return i + m_x;
}

...
};

Const en contantes globales


const INVALID_VALUE = 0;

9.7 Utilizar en métodos con valor en lugar de constantes

El uso de constantes globales debe ser restringido y debe usarse en casos muy
necesarios. Se recomienda usar métodos con valor en su lugar.

Ejemplo
int getMaxIterations() /// < NOT: MAX_ITERATIONS = 25
{
return 25;
};

29
9.8 Reutilización el Comportamiento

o Reuso de Constructores sobrecargados: Reutilizar la implementación


del constructor más especializado desde los constructores específicos. (Ref.
High Integrity CPP Rule 3.1.9)

o Implementando un Helper: Se suele utilizar este tipo de implementación


cuando existe funcionalidad común en parte de la implementación de un
método, esto se puede realizar de dos formas: (Ref. High Integrity CPP Rule
3.1.9)

o Creando una operación helper: Cuando la funcionalidad corresponde


únicamente al ámbito de la case.

o Una clase helper: Cuando la funcionalidad corresponde al ámbito de


más de una case.
Ejemplo

Reusando Constructores

class Dictionary {
private:
int m_capacity;
public:
/// < Reusa el segundo constructor
/// < con capacidad ilimitada
Dictionary ():Dictionary(-1)
{ }

Dictionary (int capacity)


{
m_capacity = capacity;
}

...
};

Operación Helper

template <class T>


class Dictionary <T> {
private:
int m_capacity, m_index; SmartPtr<T> m_items[];
public:
/// < Elimina un item por valor.
void remove (T item)
{
int i = -1;
int k = -1;
while (i < m_capacity && k == -1) {
if (m_items [++i] == item) k = i;
}
resize (k);
}

/// < Elimina un item por posición.


void removeAt (int position)
{
if (position < m_capacity) resize (position);
}

30
void resize (int position)
{
while (position < m_capacity - 1)
m_items [position] = m_items [++position];

delete m_items[--m_capacity];
}
...
};

Clase Helper

template <class T>


class Dictionary <T> {
private:
int m_capacity, m_index;
SmartPtr<T> m_items[];
public:
/// < Serializa el diccionario a XML.
void serialize (String fileName)
{
FileHandler file = FileHandler (fileName);
...
file.Save (E_FileOptions.Overwrite);
}
...
};

9.9 Macros debe ser creadas para simplificar la escritura de código y/o reusar
comportamiento genérico.

Ejemplo de simplificación:
#define SmartPtr std::tr1::shared_ptr

Ejemplo de reuso genérico:


#define CheckHandle(ptr, body) \
(void)( ((ptr) == NULL) && \
(::EMPRESA XXX::Debug::header( DERROR, __FILE__,
(__LINE__) )) && \
(::EMPRESA XXX::Debug::text("Referencia NULA : %s", body))
&& \
(::EMPRESA XXX::Debug::exit()) )

10.
9.10 Aserciones

Utilizar la clase DEBUG según la siguiente sintaxis:

Sintaxis:
DEBUG(<nivel>, <mensaje>, <argumentos>);
El nivel puede ser una de las siguiente macros:

Macro Valor
#define DWARNING 5
#define DASSERT 10
#define DINFO 15
#define DERROR 1

Ejemplo:

31
DEBUG(DINFO, ("OsirisCardChannel %s :: selectVideoSource",
getName().c_str()));

11. Patrones de Diseño

11.1 Patrón Observer

o Participantes: Deberán ser denominados como:


 Sujeto: Clase que hereda de Subject.
 Observador: Clase que hereda de Observer.

Ejemplo

class Subject
{
public:
Subject (void);

void attach (SmartPtr<Observer> observer);


void detach (SmartPtr<Observer> observer);
string getState ();
void notify ();

~Subject (void);
protected:
vector m_list;
};

class Observer
{
public:
Observer(void);
virtual void update (Subject subject) = 0;
public:
~Observer(void);
};

32
class Customer: public Subject
{
public:
Customer(void):Subject(void);
~Customer(void);
};

class AddressVerification : public Observer


{
public:
AddressVerification(void);
void update(Subject customer);
public:
~AddressVerification(void);
};

11.2 Patrón Fachada


o Participantes
 Fachada: <NombreClase>Manager, esta clase por ser de control no
sólo debe ceñirse a implementar una fachada sino que además puede
tener otras características como creación de objetos, etc.
 Participantes: <NombreClase>

33
Ejemplo

class SaleManager
{
private:
SaleManager () {}

public:
static void registerSale (SaleDocument sale,
Customer customer)
{
if (customer.hasPendingPayments ())
throw new CustomerException ("Cliente es moroso");

try
{
if (!customer.exists () && sale.isInvoice())
{
Customer.register ();
sale.setOwner (customer);
}
sale.register ();
}
catch (Exception ex)
{
throw ex;
}
}
}

/// < Uso del Patrón


void main()
{
SaleDocument sale(“55829”, “invoice”);
sale.addItem(new SaleDetail(“arroz”, 5));
sale.addItem(new SaleDetail(“leche”, 10));
Customer customer(“Juan Pérez”);

SaleManager::registerSale(sale, customer);
}

11.3 Patrón Abstract Factory


o Participantes
 AbstractFactory: <NombreClase>Factory
 ConcreteFactory: <NombreClaseDerivada>
 AbstractProduct: <NombreClase>Abstract
 ConcreteProduct: <NombreClaseDerivada>
 Cliente: <NombreClaseCliente>

34
Ejemplo

Notación UML

35
11.4 Patrón Factory Method
o Participantes
 Creator: <NombreClase>
 ConcreteCreator: <NombreClase>
o Método de Fabricación: Create<NombreClaseConcreteProduct>
 Product: <NombreClase>
 ConcreteProduct: <NombreClase>

Ejemplo

36
11.5 Patrón Singleton

Utilizar este patrón para crear elementos de comunicación DDS así como
para las fábricas.

Ejemplo:

template <class T>


class Singleton <T>
{
public:
static T* instance()
{
if (!m_isCreated)
{
m_instance = new T();
m_isCreated = True;
}
return m_instance;
}

~Singleton()
{
m_isCreated = False;
delete m_instance;
}

private:
static T * m_instance;
static Bool m_isCreated;

///
/// \brief Do not create any object by calling Constructor.
///
Singleton()
{
}
}

37
11.6 Patrón Listener

Utilizar este patrón para implementar mensajería entre objetos.


o Participantes
 EventSource/EventProducer: <NombreClase>Source
 EventObject: <NombreClase>Event
 EventListener: <NombreClase>Listener

Ejemplo:

11.7 Patrón Estrategy

Utilizar este patrón para implementar algoritmos cuya invocación responde


a eventos condicionales diversos, además cada algoritmo es independiente
y posee cierta complejidad.
o Participantes
 Context: <NombreClase>
 Strategy: <NombreClase>Strategy
 ConcreteStategy: <NombreClase>

38
Ejemplo:

11.8 Patrón Proxy

Utilizar este patrón para invocar objetos del servidor, objetos demandados
u objetos con nivel de acceso protegido.
o Participantes
 Client: <NombreClase>
 Subject: <NombreClase>
 RealSubject: <NombreClase>
 Proxy: <NombreClase>Proxy

39
Ejemplo:

40
12. Referencias

 High·Integrity C++ Coding Standard Manual Version 2.4, The Programming Research Group,
2006.    
http://www.programmingresearch.com/QAHICPP.html

 Doxygen documentation system


http://www.stack.nl/~dimitri/doxygen/index.html

41

También podría gustarte