2011-02-07 18 views
7

cabecera Soy nuevo en C/C++, estoy confundido acerca siguientes:C++ incluyen problema

  1. si debería poner las declaraciones de clase en su propio archivo de cabecera, y la implementación real en otro archivo?
  2. ¿Debo poner encabezados como <iostream> en el archivo example.h o en el archivo example.cpp?
  3. Si todas las clases tienen que utilizar <iostream>, e incluyo el archivo de cabecera de una clase en la cabecera de otra clase, significa que incluí <iostream> dos veces?
  4. Si uso muchas clases de STL, ¿cuál es una buena práctica para usar std::?
+1

# 4 es lo suficientemente clara como para merecer su propia pregunta – Cameron

+0

Estas son cuestiones dignas, pero la combinación de todos ellos en uno es "demasiado amplia". –

Respuesta

8

1.Whether debo poner las declaraciones de clase en su propio archivo de encabezado, y su aplicación real en otro archivo ?

Puede escribir la definición de una clase y la definición de los miembros de la clase por separado en el mismo archivo de encabezado si está manipulando plantillas. Además, si desea que sus miembros funcionen en línea, puede definirlos dentro de la definición de clase. En cualquier otro caso, es mejor separar la definición de la clase (archivo .hpp) y la definición de los miembros de la clase (.cpp).

2.Si debo poner encabezados como en el archivo example.h o en el archivo example.cpp ?

Depende de si necesita esos encabezados en el archivo example.h o solo en su archivo .cpp.

3. Si todas las clases tienen que utilizar, e incluyo el archivo de cabecera de una clase en cabecera de otra clase, ¿significa que incluido dos veces?

Sucede si no envuelve sus definiciones de clase por las siguientes macros:

#ifndef FOO_HPP 
#define FOO_HPP 
class { 
... 
}; 
#endif 

5. Si utilizo un lote clases STL, lo que es una buena práctica utilizar std: :?

Creo que siempre es mejor utilizar std:: cada vez en lugar de . De esta forma, solo usará los espacios de nombres que necesite y su código será más legible porque evitará conflictos de espacios de nombres (imagine dos métodos que tienen el mismo nombre y pertenecen a dos espacios de nombres diferentes).

Pero lo más importante es dónde está la pregunta número 4 de todos modos?

+1

Elimina los doble guiones bajos antes de 'FOO_HPP' y voy a votar mejor esto.;) – Maxpm

+1

@Maxpm: Hecho :) –

1

Normalmente, usted pone las declaraciones de clase (incluidas las declaraciones de los miembros) en los archivos de encabezado y las definiciones de las funciones de los miembros (métodos) en los archivos fuente. Los encabezados suelen tener nombres como *.h o *.hpp. En cuanto al punto 3, debes incluir guardias en tus encabezados para que puedan incluirse de manera segura varias veces en el mismo archivo fuente; entonces puedes incluirlos donde los necesites. No entiendo el punto n. ° 5: ¿está preguntando cuándo usar la calificación del espacio de nombres std::?

1

Para el problema "incluido el doble", aquí es un patrón común para sus archivos de encabezado:

// _BLAHCLASS_H_ should be different for each header, otherwise things will Go Bad. 
#ifndef _BLAHCLASS_H_ 
#define _BLAHCLASS_H_ 

... rest of header ... 

#endif 
+4

Los nombres que comienzan con dos guiones bajos están reservados para la implementación del compilador; debe usar un patrón diferente para sus guardias de inclusión (por ejemplo, 'BLAHCLASS_H_INCLUDED'). –

+1

Estoy de acuerdo con el punto general, pero ¿cuál es el trato con las personas que usan doble guión bajo (lo veo en todas partes). ¿No son estos nombres reservados para implementaciones? (Se ven feos, también) –

+0

Hoy aprendí algo sobre el doble guión bajo. – geofftnz

2
  1. general, sí. Ayuda con la organización. Sin embargo, en proyectos pequeños, puede que no sea tan importante.

  2. estoy teniendo problemas para entender la pregunta aquí. Si está preguntando dónde colocar la directiva #include, el archivo de implementación debe incluir el archivo de encabezado.

  3. Sí, pero el uso de include guards evita múltiples inclusiones.

1
  1. Mientras que no son las plantillas, por lo general sí. Las plantillas (para bien o para mal) deben colocarse en los encabezados.
  2. Prefiero hacer que cada uno de mis encabezados sea "independiente", por lo que si se necesita otro encabezado para que funcione, incluye ese encabezado (por ejemplo, si tengo una clase que usa std::string, el encabezado de esa clase #include <string>.
  3. No. con unas pocas excepciones especiales, se requieren las cabeceras estándar para ser escrito para que pueda incluir más de una vez y sin que cambiar nada (la principal excepción es assert.h/cassert, que puede tener sentido para incluir más más de una vez).
  4. No estoy seguro exactamente de lo que está preguntando. Si está preguntando sobre una directiva de uso como using namespace std;, entonces es generalmente (aunque ciertamente no universal) no me gustó. Una declaración de uso como using std::vector; generalmente se considera menos problemática.
+0

Hay formas de separar la implementación de una plantilla de su declaración, pero eso probablemente esté más allá del alcance de esta pregunta. – Maxpm

2
  1. Normalmente debería hacerlo, pero para proyectos relativamente pequeños puede evitar tener un archivo de implementación tanto como sea posible;
  2. Si su encabezado usa solo tipos incompletos del <iostream>, puede evitar incluirlo, pero necesitará forward declarations para estos tipos (consulte When to use forward declaration?). Sin embargo, para simplificar, si el tipo usa una plantilla, normalmente incluyo el encabezado respectivo;
  3. No. El include guards garantiza que un encabezado se incluye solo una vez en el mismo translation unit;
  4. Una buena práctica común es no poner using namespace std en un archivo de encabezado. Tenga en cuenta los conflictos de espacio de nombres también;