0% encontró este documento útil (0 votos)
6 vistas17 páginas

Good Practice

Cargado por

perfect 221
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
6 vistas17 páginas

Good Practice

Cargado por

perfect 221
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 17

---------

CAPÍTULO 0
---------

0.2: Las mejores prácticas son cosas que deberías hacer, porque de esa forma
se considera generalmente un estándar o muy recomendable. Es decir, o todo
el mundo lo hace así (y si lo haces de otro modo, estarás haciendo algo que
la gente no espera), o es superior a las alternativas.

0.4: Nombra tus archivos de código algo.cpp, donde algo es un nombre de tu


elección, y .cpp es la extensión que indica que el archivo es un archivo
fuente C++.

0.7: Cree un nuevo proyecto para cada nuevo programa que escriba.

0.9: Utiliza la configuración de depuración cuando desarrolles tus programas.


Cuando estés listo para distribuir tu ejecutable a otros, o quieras probar
el rendimiento, utiliza la configuración de compilación de lanzamiento.

0.10: Desactive las extensiones del compilador para asegurarse de que sus
programas (y prácticas de codificación) siguen cumpliendo los estándares
de C++ y funcionarán en cualquier sistema.

0.11: No dejes que se acumulen los avisos. Resuélvelos a medida que los
encuentres (como si fueran errores).
De lo contrario, un aviso sobre un problema grave puede perderse entre
avisos sobre problemas no graves.

Sube al máximo los niveles de alerta, sobre todo mientras aprendes. Te


ayudará a identificar posibles problemas.

Active la opción "Tratar las advertencias como errores". Esto le obligará


a resolver todos los problemas que causen advertencias.

---------
CAPÍTULO 1
---------

1.2: Comenta tu código abundantemente, y escribe tus comentarios como si


hablaras con alguien que no tiene ni idea de lo que hace el código. No des
por sentado que recordarás por qué has tomado determinadas decisiones.
1.3: Aunque el lenguaje lo permite, evite definir varias variables del mismo
tipo en una misma sentencia. En su lugar, defina cada variable en una
sentencia independiente en su propia línea (y luego utilice un comentario
de una sola línea para documentar para qué se utiliza).

1.4: Favorecer la inicialización utilizando llaves siempre que sea posible.

Inicialice sus variables en el momento de la creación.

1.5 Emite una nueva línea cada vez que se completa una línea de salida.

Prefiera '\n' a std::endl cuando envíe texto a la consola.

Existe cierto debate sobre si es necesario inicializar una variable


inmediatamente antes de darle un valor proporcionado por el usuario a
través de otra fuente (por ejemplo, std::cin), ya que el valor
proporcionado por el usuario simplemente sobrescribirá el valor de
inicialización.
En línea con nuestra recomendación anterior de que las variables deben
ser siempre inicializadas, la mejor práctica es inicializar la variable
primero.

1.7: Cuando trabajes en un programa existente, utiliza las convenciones de ese


programa (aunque no se ajusten a las mejores prácticas modernas). Utiliza
las mejores prácticas modernas cuando escribas nuevos programas.

1.8: Sus líneas no deben superar los 80 caracteres.

Se recomienda utilizar la función de formateo automático para mantener la


coherencia del estilo de formateo del código.

1.11: Los nuevos programadores a menudo intentan escribir un programa entero de


una vez, y luego se agobian cuando produce muchos errores.
Una estrategia mejor es añadir una pieza cada vez, asegurarse de que compila
y probarla.
Cuando estés seguro de que funciona, pasa a la siguiente parte.

---------
CAPÍTULO 2
---------

2.2: Su función principal debe devolver el valor 0 si el programa se ejecuta


normalmente.
Asegúrese de que sus funciones con tipos de retorno no vacíos devuelven un
valor en todos los casos.
Si no se devuelve un valor de una función que devuelve un valor, se
producirá un comportamiento indefinido.

Siga la mejor práctica DRY: "no te repitas".


Si necesitas hacer algo más de una vez, considera cómo modificar tu código
para eliminar tanta redundancia como sea posible.
Las variables pueden utilizarse para almacenar los resultados de cálculos
que deban utilizarse más de una vez (para no tener que repetir el cálculo).
Las funciones pueden usarse para definir una secuencia de sentencias que
queremos ejecutar más de una vez.
Y los bucles (que veremos en un capítulo posterior) pueden utilizarse para
ejecutar una sentencia más de una vez.

2.3: No coloque una sentencia return al final de una función que no devuelva
valores.

2.5: Defina sus variables locales tan cerca de su primer uso como sea razonable.

2.7: Cuando trate errores de compilación en sus programas, resuelva siempre


primero el primer error producido y luego vuelva a compilar.

Mantenga los nombres de los parámetros en las declaraciones de las


funciones.

2.8: Cuando añadas nuevos archivos de código a tu proyecto, dales una


extensión .cpp.

2.9: Utilice prefijos de espacio de nombres explícitos para acceder a


identificadores definidos en un espacio de nombres.

2.11: Por lo general, los archivos de cabecera no deben contener definiciones


de funciones y variables, para no infringir la regla de una definición.
Se hace una excepción con las constantes simbólicas.

Utilice el sufijo .h para nombrar los archivos de cabecera.

Si un archivo de cabecera está emparejado con un archivo de código (por


ejemplo, add.h con add.cpp), ambos deben tener el mismo nombre base (add).

Los archivos fuente deben #incluir el archivo de cabecera correspondiente


(si existe).

Cuando incluya un archivo de cabecera de la biblioteca estándar, utilice


la versión sin la extensión .h si existe. Las cabeceras definidas por el
usuario deben seguir utilizando la extensión .h.

Cada archivo debe #incluir explícitamente todos los archivos de cabecera


que necesita para compilar. No confíe en cabeceras incluidas
transitoriamente desde otras cabeceras.

Para maximizar la posibilidad de que los includes que faltan sean marcados
por el compilador, ordene sus #includes de la siguiente manera:
1. El archivo de cabecera emparejado
2. Otras cabeceras del proyecto
3. Cabeceras de bibliotecas de terceros
4. Cabeceras de bibliotecas estándar
Las cabeceras de cada grupo deben ordenarse alfabéticamente.

2.12: Prefiera los protectores de cabecera a #pragma una vez para obtener la
máxima portabilidad.

---------
CAPÍTULO 3
---------

3.10: Utilice una herramienta de análisis estático en sus programas para ayudar
a encontrar áreas en las que su código no cumple con las mejores prácticas.

---------
CAPÍTULO 4
---------

4.2: Utilice una lista de parámetros vacía en lugar de void para indicar que
una función no tiene parámetros.

4.3: Para lograr la máxima compatibilidad, no debe suponer que las variables
son mayores que el tamaño mínimo especificado.

4.4: Prefiera los tipos abreviados que no utilizan el sufijo int ni el prefijo
signed.

4.5: Prefiera los números con signo a los números sin signo para almacenar
cantidades (incluso cantidades que no deben ser negativas) y realizar
operaciones matemáticas. Evita mezclar números con y sin signo.

4.6: • Prefiera int cuando el tamaño del entero no importe (por ejemplo, el
número siempre cabrá dentro del rango de un entero con signo de 2 bytes).
Por ejemplo, si está pidiendo al usuario que introduzca su edad, o que
cuente del 1 al 10, no importa si int tiene 16 o 32 bits (los números
cabrán de cualquier forma). Esto cubrirá la gran mayoría de los casos con
los que probablemente te encuentres.
• Prefiera std::int#_t cuando almacene una cantidad que necesite un rango
garantizado.
• Prefiera std::uint#_t cuando manipule bits o cuando necesite un
comportamiento envolvente bien definido.

Evite lo siguiente siempre que sea posible:

• Tipos sin signo para contener cantidades


• Los tipos enteros de ancho fijo de 8 bits
• Los tipos de ancho fijo rápido y mínimo
• Cualquier entero de ancho fijo específico del compilador -- por ejemplo,
Visual Studio define __int8, __int16, etc...

4.8: Asegúrate siempre de que el tipo de tus literales coincide con el tipo de
las variables a las que se asignan o que se utilizan para inicializar. De
lo contrario, se producirá una conversión innecesaria, posiblemente con
pérdida de precisión.

Es preferible utilizar double en lugar de float a menos que se disponga de


poco espacio, ya que la falta de precisión de un float suele dar lugar a
imprecisiones.

Evite por completo la división por 0, incluso si su compilador la admite.

4.11: Ponga los caracteres independientes entre comillas simples (por ejemplo,
't' o '\n', no "t" o "\n"). Esto ayuda al compilador a optimizar de forma
más eficaz.

Evite los literales con varios caracteres (por ejemplo, '56').

4.13: Coloque const antes del tipo (porque es más idiomático hacerlo).

No uses const cuando pases por valor.

No uses const cuando devuelvas por valor.


Prefiera las variables constantes a las macros tipo objeto con texto de
sustitución.

4.14: Cualquier variable que no deba modificarse tras la inicialización y cuyo


inicializador se conozca en tiempo de compilación debe declararse como
constexpr.
Cualquier variable que no deba modificarse tras la inicialización y cuyo
inicializador no se conozca en tiempo de compilación debe declararse como
const.

4.15: Prefiera el sufijo literal L (mayúsculas) a l (minúsculas).

Evite los números mágicos en su código (utilice variables constexpr en su


lugar).

4.17: Si utiliza std::getline() para leer cadenas, utilice el manipulador de


entrada std::cin >> std::ws para ignorar los espacios en blanco iniciales.

No pasar std::string por valor, ya que hacer copias de std::string es


costoso. Prefiera parámetros std::string_view.

4.18: Prefiera std::string_view a std::string cuando necesite una cadena de sólo


lectura, especialmente para parámetros de funciones.

---------
CAPÍTULO 5
---------

5.1: Utilice paréntesis para dejar claro cómo debe evaluarse una expresión no
trivial (aunque sean técnicamente innecesarios).

Las expresiones con un único operador de asignación no necesitan tener el


operando derecho de la asignación entre paréntesis.

Aparte de las reglas de precedencia y asociatividad de los operadores,


suponga que las partes de una expresión pueden evaluarse en cualquier
orden. Asegúrese de que las expresiones que escribe no dependen del orden
de evaluación de esas partes.

5.4: Es preferible utilizar la versión prefijada de los operadores de incremento


y decremento, ya que suelen ser más eficaces y es menos probable que se
produzcan problemas extraños con ellos.
5.5: Evite utilizar el operador coma, excepto dentro de los bucles for.

Ponga siempre entre paréntesis la parte condicional del operador


condicional, y considere también la posibilidad de poner entre paréntesis
el operador condicional completo.

Utilice el operador condicional sólo para condicionales sencillas en las


que utilice el resultado y mejoren la legibilidad.

5.6: No añadas == o != innecesarios a las condiciones. Dificultan la lectura


sin aportar ningún valor añadido.

5.7: Si se pretende que NOT lógico opere sobre el resultado de otros operadores,
los otros operadores y sus operandos deben ir entre paréntesis.

Cuando mezcle AND lógico y OR lógico en una única expresión, ponga


explícitamente entre paréntesis cada operación para asegurarse de que se
evalúan como usted pretende.

---------
CAPÍTULO O
---------

O.1: La manipulación de bits es una de las pocas ocasiones en las que debe
utilizar sin ambigüedad enteros sin signo (o std::bitset).

O.2: Para evitar sorpresas, utilice los operadores bitwise con operandos sin
signo o std::bitset.

---------
CAPÍTULO 6
---------

6.1: Mantenga el nivel de anidamiento de sus funciones en 3 o menos. Si tu


función necesita más niveles de anidamiento, considera la posibilidad de
refactorizarla en subfunciones.

6.3: Defina las variables en el ámbito más limitado posible. Evita crear nuevos
bloques cuyo único propósito sea limitar el ámbito de las variables.

6.4: Considere el uso de un prefijo "g" o "g_" al nombrar variables globales


no-const, para ayudar a diferenciarlas de las variables locales y los
parámetros de función.

6.5: Evitar la sombra variable.

6.8: Utilice variables locales en lugar de globales siempre que sea posible.

6.9: Si necesitas constantes globales y tu compilador es compatible con C++17,


prefiere definir variables globales constexpr inline en un fichero de
cabecera.

6.10: Inicialice sus variables locales estáticas. Las variables locales estáticas
sólo se inicializan la primera vez que se ejecuta el código, no en
llamadas posteriores.

Evite las variables locales estáticas a menos que la variable nunca


necesite ser reiniciada.

6.12: Prefiera los espacios de nombres explícitos a las sentencias using. Evite
el uso de directivas siempre que sea posible. Las declaraciones de uso
pueden utilizarse dentro de bloques.

6.13: No utilice la palabra clave inline para solicitar la expansión en línea


de sus funciones.

Evite el uso de la palabra clave inline para funciones a menos que tenga
una razón específica y convincente para hacerlo.

6.14: Utilice un tipo de retorno constexpr para las funciones que necesitan
devolver una constante en tiempo de compilación.

Utilice consteval si tiene una función que debe ejecutarse en tiempo de


compilación por alguna razón (por ejemplo, rendimiento).

---------
CAPÍTULO 7
---------

7.2: Considere la posibilidad de colocar las sentencias individuales asociadas


a un if o un else en bloques (sobre todo mientras esté aprendiendo). Los
desarrolladores de C++ más experimentados a veces ignoran esta práctica
en favor de un espaciado vertical más ajustado.

7.4: Prefiera las sentencias switch a las cadenas if-else cuando haya que elegir.
Coloque el caso por defecto en último lugar en el bloque de conmutación.

Cada conjunto de sentencias bajo una etiqueta debe terminar en una


sentencia break o return. Esto incluye las sentencias bajo la última
etiqueta del switch.

7.5: Utilice el atributo [[fallthrough]] (junto con una sentencia null) para
indicar un fallthrough intencionado.

Si define variables utilizadas en una sentencia case, hágalo en un bloque


dentro del case.

7.6: Evite las sentencias goto (a menos que las alternativas sean
significativamente peores para la legibilidad del código).

7.7: Favorecer while(true) para bucles infinitos intencionados.

Las variables de bucle deben ser de tipo int (con signo).

7.8: Prefiera los bucles while a los do-while en igualdad de condiciones.

7.9: Evite el operador != cuando realice comparaciones numéricas en la


condición del bucle for.

La definición de múltiples variables (en la sentencia init) y el uso del


operador coma (en la expresión final) son aceptables dentro de una
sentencia for.

Prefiera los bucles for a los bucles while cuando haya una variable de
bucle obvia.
Prefiera los bucles while a los bucles for cuando no haya una variable de
bucle obvia.

7.10: Utilice break y continue cuando simplifiquen la lógica de su bucle.

Utilice los retornos anticipados cuando simplifiquen la lógica de su


función.

7.11: Sólo use un halt si no hay una forma segura de retornar normalmente desde
la función principal. Si no has deshabilitado las excepciones, prefiere
usar excepciones para manejar errores de forma segura.
7.12: Escriba su programa en unidades pequeñas y bien definidas (funciones o
clases), compile a menudo y pruebe su código sobre la marcha.

7.13: Aspire a una cobertura de ramas del 100% de su código.

Utilice la prueba 0, 1, 2 para asegurarse de que sus bucles funcionan


correctamente con diferentes números de iteraciones.

Pruebe diferentes categorías de valores de entrada para asegurarse de que


su unidad los maneja correctamente.

7.17: Utilice aserciones para documentar casos que deberían ser lógicamente
imposibles.

7.19: Utiliza std::random_device para sembrar tus PRNGs (a menos que no esté
implementado correctamente para tu compilador/arquitectura de destino).

Siembra un generador de números pseudoaleatorios una sola vez y no lo


vuelvas a sembrar.

---------
CAPÍTULO 8
---------

8.3: Evite las conversiones estrechas siempre que sea posible. Si necesita
realizar una, utilice static_cast para que sea una conversión explícita.

8.5: Evite utilizar moldes de tipo C.

Favorece static_cast cuando necesites convertir un valor de un tipo a


otro tipo.

8.6: Nombra tus alias de tipo empezando con mayúscula y no utilices un sufijo
(a menos que tengas una razón específica para hacer lo contrario).

Prefiera los alias de tipos a los typedefs.

Utilice los alias de tipos con sensatez, cuando supongan una clara ventaja
para la legibilidad o el mantenimiento del código.

8.7: Utilice la deducción de tipo para sus variables, a menos que necesite
comprometerse con un tipo específico.
8.8: Favorecer los tipos de retorno explícitos frente a la deducción de tipos
de retorno de función para funciones normales.

8.9: Utilice la sobrecarga de funciones para simplificar su programa.

8.12: Si la función tiene una declaración forward (especialmente una en un


fichero de cabecera), ponga el argumento por defecto allí. En caso
contrario, coloque el argumento por defecto en la definición de la función.

8.13: Utilice una sola letra mayúscula (empezando por T) para nombrar sus tipos
de plantilla (por ejemplo, T, U, V, etc...)

8.14: Favorezca la sintaxis normal de llamada a función cuando utilice plantillas


de función.

Utilice plantillas de funciones para escribir código genérico que pueda


funcionar con una amplia variedad de tipos siempre que lo necesite.

8.15: Siéntase libre de utilizar plantillas de funciones abreviadas con un único


parámetro automático, o donde cada parámetro automático debe ser un tipo
independiente (y su estándar de lenguaje está establecido en C++20 o más
reciente).

---------
CAPÍTULO 9
---------

9.3: Al definir una referencia, coloque el signo ampersand junto al tipo (no
junto al nombre de la variable de referencia).

9.4: Favorece las referencias lvalue a const sobre las referencias lvalue a
non-const a menos que necesites modificar el objeto referenciado.

9.5: Favorezca el paso por referencia const sobre el paso por referencia
no-const a menos que tenga una razón específica para hacer lo contrario
(por ejemplo, la función necesita cambiar el valor de un argumento).

Pasar tipos fundamentales por valor, y tipos de clase (o estructura) por


referencia constante.

Prefiera el paso por valor para los objetos que son baratos de copiar, y
el paso por referencia constante para los objetos que son caros de copiar.
Si no estás seguro de si un objeto es barato o caro de copiar, prefiere
pasar por referencia const.

9.6: Al declarar un tipo de puntero, coloque el asterisco junto al nombre del


tipo.

Inicializa siempre tus punteros.

9.7: Valore inicializar sus punteros (para que sean punteros nulos) si no los
está inicializando con la dirección de un objeto válido.

Utilice nullptr cuando necesite un literal de puntero nulo para


inicializar, asignar o pasar un puntero nulo a una función.

Un puntero debe contener la dirección de un objeto válido, o bien tener el


valor nullptr. De esta forma, sólo tendremos que comprobar si un puntero
es nulo, y podremos asumir que cualquier puntero no nulo es válido.

Prefiera las referencias a los punteros a menos que se necesiten las


capacidades adicionales que proporcionan los punteros.

9.9: Prefiera el paso por referencia al paso por dirección a menos que tenga
una razón específica para utilizar el paso por dirección.

9.11: Evite devolver referencias a variables estáticas locales no-const.

Prefiera el retorno por referencia al retorno por dirección a menos que la


capacidad de devolver "ningún objeto" (usando nullptr) sea importante.

9.12: Si desea una referencia const, vuelva a aplicar el calificador const


incluso cuando no sea estrictamente necesario, ya que deja clara su
intención y ayuda a evitar errores.

Si desea un puntero const, vuelva a aplicar el calificador const incluso


cuando no sea estrictamente necesario, ya que deja clara su intención y
ayuda a evitar errores.

---------
CAPÍTULO 10
---------

10.1: Denomine los tipos definidos por el programa empezando por mayúscula y
sin sufijo.
Un tipo definido por el programa utilizado en un solo archivo de código
debe definirse en ese archivo de código lo más cerca posible del primer
punto de uso.

Un tipo definido por el programa utilizado en varios archivos de código


debe definirse en un archivo de cabecera con el mismo nombre que el tipo
definido por el programa y luego #incluirse en cada archivo de código
según sea necesario.

10.2: Nombra tus tipos enumerados empezando por mayúscula.


Nombra tus enumeradores empezando por una letra minúscula.

Es preferible colocar las enumeraciones dentro de una región de ámbito con


nombre (como un espacio de nombres o una clase) para que los enumeradores
no contaminen el espacio de nombres global.

10.3: Evite asignar valores explícitos a sus enumeradores a menos que tenga una
razón de peso para hacerlo.

Especifique el tipo base de una enumeración sólo cuando sea necesario.

10.4: Favorezca las enumeraciones con alcance sobre las enumeraciones sin alcance
a menos que haya una razón de peso para hacer lo contrario.

10.6: Prefiera la forma de lista con corchetes (no copia) al inicializar agregados.

Cuando se añade un nuevo miembro a un agregado, lo más seguro es añadirlo


al final de la lista de definiciones para que los inicializadores de otros
miembros no se desplacen.

10.7: Proporcione un valor por defecto para todos los miembros. Esto asegura que
sus miembros serán inicializados incluso si la definición de la variable
no incluye una lista de inicializadores.

Si no se van a proporcionar valores inicializadores explícitos para un


agregado, prefiera la inicialización de valores (con un inicializador de
llaves vacío) a la inicialización por defecto (sin llaves).

10.9: Cuando utilice un puntero para acceder al valor de un miembro, utilice el


operador de selección de miembro desde puntero (->) en lugar del operador
de selección de miembro (.).

---------
CAPÍTULO 11
---------

11.2: Inicialice explícitamente sus matrices (incluso cuando el tipo de elemento


sea autoinicializable).

11.7: Prefiera std::string_view a std::string y a las cadenas estilo C cuando


sólo necesite acceso de sólo lectura a una cadena (a menos que no pueda
garantizar que la cadena que se está visualizando permanecerá viva durante
el tiempo de vida de std::string_view, en cuyo caso debería preferir
std::string).

Prefiera pasar cadenas usando std::string_view (por valor) en lugar de


const std::string&, a menos que su función llame a otras funciones que
requieran cadenas estilo C o parámetros std::string.

11.8: Favorece la sintaxis de puntero (*) sobre la sintaxis de matriz ([]) para
parámetros de función de matriz.

11.11: Establece los punteros eliminados a nullptr a menos que salgan del ámbito
inmediatamente después.

11.13: En las declaraciones de elementos de bucles for-each, si sus elementos


son tipos no fundamentales, utilice referencias o referencias const por
razones de rendimiento.

11.16: Pasar siempre std::array por referencia o referencia constante

11.19: A menos que se especifique lo contrario, no asuma que los algoritmos de


la biblioteca estándar se ejecutarán en una secuencia particular.
std::for_each, std::copy, std::copy_backward, std::move, y
std::move_backward tienen garantías secuenciales.

Prefiera utilizar funciones de la biblioteca de algoritmos a escribir sus


propias funciones para hacer lo mismo.

---------
CAPÍTULO 12
---------

12.4: En general, favorezca la iteración sobre la recursividad, excepto cuando la


recursividad realmente tenga sentido.
12.8: Sólo inicialece variables en la captura si su valor es corto y su tipo es
obvio. De lo contrario, es mejor definir la variable fuera de la lambda y
capturarla.

Intente evitar las lambdas mutables. Las lambdas no mutables son más
fáciles de entender y no sufren los problemas anteriores, así como otros
más peligrosos que surgen cuando se añade la ejecución paralela.

---------
CAPÍTULO 13
---------

13.2: Nombre sus clases empezando por mayúscula.

Utilice la palabra clave struct para las estructuras que sólo contienen datos.
Utilice la palabra clave class para objetos que tengan tanto datos como funciones.

13.3: Haz que las variables miembro sean privadas y las funciones miembro
públicas, a menos que tengas una buena razón para no hacerlo.

13.4: Los getters deben devolver por valor o referencia const.

13.5: Favorecer la inicialización por valor frente a la inicialización por


defecto para los objetos de clase.

Favorecer la inicialización de los corchetes para inicializar los objetos


de clase.

Si tienes constructores en tu clase y necesitas un constructor por defecto


que no haga nada (por ejemplo, porque todos tus miembros se inicializan
usando inicialización de miembros no estática), usa = default.

Inicialice siempre todas las variables miembro de sus objetos.

13.6: Utilice listas de inicializadores de miembros para inicializar las


variables miembro de su clase en lugar de asignarlas.

13.8: Si tienes varios constructores con la misma funcionalidad, utiliza


constructores delegados para evitar duplicar código.

13.12: Haga que cualquier función miembro que no modifique el estado del objeto
de la clase sea const, para que pueda ser llamada por objetos const.
13.13: Acceda a los miembros estáticos por el nombre de la clase (utilizando el
operador de resolución de ámbito) en lugar de a través de un objeto de la
clase (utilizando el operador de selección de miembros).

---------
CAPÍTULO 14
---------

14.1: Al sobrecargar operadores, es mejor mantener la función de los operadores


lo más cerca posible de la intención original de los operadores.

Si el significado de un operador sobrecargado no es claro e intuitivo,


utilice en su lugar una función con nombre.

14.3: Prefiera sobrecargar operadores como funciones normales en lugar de friends


si es posible hacerlo sin añadir funciones adicionales.

14.7: Defina únicamente operadores sobrecargados que tengan un sentido intuitivo


para su clase.

14.13: Evite utilizar la inicialización por copia y utilice en su lugar la


inicialización uniforme.

14.14: Considere la posibilidad de hacer explícitos los constructores y las


funciones miembro de conversión definidas por el usuario para evitar
errores de conversión implícitos.

---------
CAPÍTULO 16
---------

16.3: Implemente el tipo de relación más sencillo que satisfaga las necesidades
de su programa, no lo que parezca correcto en la vida real.

16.7: Si proporciona la construcción de listas, es una buena idea proporcionar


también la asignación de listas.

---------
CAPÍTULO 17
---------

17.5: Favorecer a los miembros privados frente a los protegidos.


Utilice la herencia pública a menos que tenga una razón específica para
hacer lo contrario.

17.9: Evite la herencia múltiple a menos que las alternativas conduzcan a una
mayor complejidad.

---------
CAPÍTULO 18
---------

18.2: Nunca llame a funciones virtuales desde constructores o destructores.

18.3: Utilice la palabra clave virtual en las funciones virtuales de una clase base.
Utilice el especificador override (pero no la palabra clave virtual) en
funciones override en clases derivadas.

También podría gustarte