Pregunta

¿Hay algún patrón semejante de dependencias que no es posible mantener todo en archivos de cabecera única? ¿Y si nos impusieron un dominio de una clase por cada cabecera única?

A los efectos de esta pregunta, vamos a ignorar las cosas estáticas:)

¿Fue útil?

Solución

Estoy al tanto de ninguna característica en C ++ estándar, a excepción de la estática, que ya hemos mencionado, las cuales requieren una biblioteca para definir una unidad de traducción completa (en lugar de sólo los encabezados). Sin embargo, no es recomendable hacer eso, porque cuando lo hace, se fuerza a todos sus clientes que recompilar toda su base de código siempre que cambie su biblioteca. Si está utilizando archivos de origen o una biblioteca estática o una forma librería dinámica de la distribución, la biblioteca puede ser cambiado / actualizado / modificado sin forzar a todos a volver a compilar.

Otros consejos

Es posible, me gustaría decir, en la condición expresa de no utilizar una serie de funciones de idioma:. Como habrá notado, algunos usos de la palabra clave static

Se puede requerir unos cuantos truco, pero que puede ser revisado.

  1. Usted tendrá que mantener la distinción cabecera / fuente cada vez que se necesita para romper un ciclo de dependencia, a pesar de que los dos archivos serán archivos de cabecera en la práctica.
  2. Free-funciones (no-plantilla) deben ser declarados en línea, el compilador no puede en línea, pero si se declaran para que no se quejó de que han sido redefinido cuando el cliente builts su librería / ejecutable.
  3. A nivel mundial compartida de datos (variables globales y los atributos estáticos clase) debe ser emulado usando el atributo estática local en funciones / métodos de clase. En la práctica, poco importa en lo que se refiere a la persona que llama (sólo se suma ()). Tenga en cuenta que en C ++ 0x esto se convierte en la manera preferida porque se garantiza que sea seguro para subprocesos al tiempo que protege del fiasco orden de inicialización, hasta entonces ... no es seguro para subprocesos;)

El respeto de esos 3 puntos, creo que sería capaz de escribir una biblioteca sólo de encabezado de pleno derecho (alguien ve algo más echaba de menos?)

Una serie de bibliotecas Boost han utilizado trucos similares para ser sólo de encabezado a pesar de que su código no estaba completamente plantilla. Por ejemplo Asio hace muy consciente y propone la alternativa usando banderas (ver notas de la versión para Asio 1.4.6 ):

  • clientes que sólo necesitan un par de características no necesita preocuparse acerca de la construcción / vinculación, que acaba de agarrar lo que necesitan
  • clientes que confían en que sea un poco más o desean reducir el tiempo de compilación se les ofrece la posibilidad de construir su propia biblioteca Asio (con su propio conjunto de banderas) y luego se incluyen las cabeceras "ligeros"

De esta manera (al precio de algo más de esfuerzo por parte de los desarrolladores de la biblioteca) los clientes obtienen su pastel y comérselo también. Es una buena solución bastante creo.

Nota: Me pregunto si las funciones static podrían ser inline, yo prefiero usar espacios de nombres anónimos a mí mismo por lo que nunca realmente se veía en él ...

La una clase por regla cabecera no tiene sentido. Si esto no funciona:

#include <header1>
#include <header2>

A continuación, algunas variaciones de esta voluntad:

#include <header1a>
#include <header2>
#include <header1b>

Esto podría resultar en menos de una clase por cabecera, pero siempre se puede utilizar (void *) y yesos y las funciones en línea (en cuyo caso el 'inline' probablemente será debidamente ignorado por el compilador). Así que la pregunta, me parece, puede reducirse a:

class A
{
// ...
void *pimpl;
}

¿Es posible que la puesta en práctica privada, pimpl, depende de la declaración de A? Si es así, pimpl.cpp (como cabecera) debe preceder y seguir A. H. Pero ya que siempre se puede, una vez más, el uso (void *) y yesos y las funciones en línea en las cabeceras anteriores, se puede hacer.

Por supuesto, puedo estar equivocado. En cualquiera de los casos:. Ick

En mi larga carrera, no he encontrado patrón de dependencia que no permitirían la ejecución sólo de encabezado.

mente que si usted tiene dependencias circulares entre las clases, es posible que tenga que recurrir a cualquier interfaz abstracto - paradigma aplicación concreta, o el uso de plantillas (utilizando plantillas le permite reenviar referencias propiedades / métodos de los parámetros de plantilla, que se resuelven más tarde durante la instanciación).

Esto no quiere decir que siempre se debe aspirar a bibliotecas sólo de encabezado. Muy buenos que sean, que debe reservarse a la plantilla y el código en línea. No deben incluir cálculos complejos sustanciales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top