Estoy más o menos de acuerdo con Vicente en que si usas objetos, entonces los constructores de esos objetos son los lugares para realizar dicha inicialización de hardware.
Pero me disgustan mucho los nombres como "IOManager", porque no transmite lo que hace la cosa (los gerentes generalmente no hacen nada útil, ¿verdad?) y probablemente agrupan las acciones de manera incorrecta, lo que da el comentario clásico de las mayúsculas C indica que no pueden ver lo que se hace cuando se construye un objeto IOManager. Eso no es culpa de OO, es la consecuencia de una mala denominación y / o partición. No es el código de inicialización el que debe agruparse en conjunto, sino el uso de un periférico (inicialización y uso operativo).
Supongamos que utiliza un bus SPI, un LCD o un sensor de corriente analógico. OMI: el objeto que inicialice debe tener un nombre después de su uso, por lo tanto (por ejemplo) un LCD HD44780 que se utiliza como salida de registro. La creación del objeto debería ser algo así como
HD44780 logger( ... );
Lo que está en ... depende de qué tan flexible es el objeto HD44780. Si los pines y el tamaño (líneas x columnas) y otros detalles son totalmente fijos (podría ser el caso de un proyecto, pero es una mala idea para una biblioteca (reutilizable)) este conocimiento podría estar dentro de la clase HD44780. Si no, pase esta información como parámetros. Si tiene los recursos, pase los objetos que representan los pines. En ese caso, la inicialización de los pines se realiza en los constructores de pines (tal vez desee un puerto (= un conjunto de pines) para el d4-d7).
gpio lcd_e( 12 );
...
HD44780( lcd_e, ... );
Esto coloca la inicialización de los pines en el lugar en el que realmente debería estar: la clase de la biblioteca de pines.
Si no puede pagar la sobrecarga de objetos por pines, considere pasar números de pines y haga que el HD44780 llame a la biblioteca de pines para realizar la inicialización. Si usa macros o funciones en línea para acceder a los pines, esto puede ser tan eficiente como usar los pines directamente (algo así como la biblioteca de Arduino Wiring).
Una abstracción de OO ofrece flexibilidad, reutilización y buena estructura de código (y parece familiar para un programador de OO), pero no es gratis: esos objetos ocupan RAM, y llamar a funciones virtuales toma tiempo y bloquea las optimizaciones (pero la optimización del tiempo de enlace mejora cada vez más al eliminar dichos gastos generales). Por lo tanto, prefiero una aplicación basada en plantilla / clase estática que evite esta sobrecarga para las jerarquías conocidas en tiempo de compilación. Esto también tiene un costo: parece un poco extraño, incluso para los programadores experimentados de C ++. Pero puede ser tan eficiente como el código C dedicado. Compruebe ¿Objetos? ¡No, gracias! por una explicación más detallada.
Odin Holmes aboga por un enfoque aún más radical, donde cada módulo especifica sus requisitos de inicialización, que luego se combinan (¡en tiempo de compilación!). Múltiples escrituras en diferentes campos de bits del mismo registro se fusionan en una asignación.