2009-05-23 9 views
5

Soy bastante nuevo en C++ y he visto un montón de código que tiene definiciones de método en los archivos de encabezado y no declaran el archivo de encabezado como clase. ¿Puede alguien explicarme por qué y cuándo harías algo como esto? ¿Es esto una mala práctica?Cuándo usar archivos de encabezado que no declaran una clase pero tienen definiciones de función

¡Gracias de antemano!

+0

¿quiere decir encabezados sin clase? no estoy seguro de lo que quiere decir con "que no declara una clase", debido a los diferentes usos de "declarar una clase" en la comunidad SO. –

+0

Sí, me refiero a un encabezado sin clase, no estaba seguro de cómo explicarlo. Básicamente es un archivo de encabezado que simplemente tiene un montón de definiciones de funciones. –

Respuesta

11

¿Es esta una mala práctica?

No en general. Hay muchas bibliotecas que son header only, lo que significa que solo envían archivos de encabezado. Este puede ser visto como una alternativa ligera a las librerías compiladas.

Más importante aún, sin embargo, hay un caso en el que no se puede usar unidades de compilación precompiladas separadas: las plantillas deben estar especializadas en la misma unidad de compilación en la que se declaran. Esto puede sonar arcano, pero tiene una consecuencia simple:

Las plantillas de funciones (y clases) no se pueden definir dentro de los archivos cpp y se pueden usar en otro lugar; en su lugar, tienen para ser definidos dentro de los archivos de encabezado directamente (con algunas excepciones notables).

Además, las clases en C++ son puramente opcionales, mientras que pueden objeto del programa orientado en C++, un montón de código bueno no lo hace. Las clases complementan los algoritmos en C++, y no al revés.

-1

En C++, las funciones no tienen que ser miembros de las clases.

+1

No es que mi propia respuesta fuera buena, pero no veo cómo responde "¿Puede alguien explicarme por qué y cuándo harías algo como esto? ¿Es esto una mala práctica?". Obviamente es legal ya que lo vio en el código de trabajo. – Uri

1

Un archivo H es simplemente una manera de incluir un montón de declaraciones. Muchas cosas en C++ son declaraciones útiles, incluyendo clases, tipos, constantes, funciones globales, etc.

C++ tiene una fuerte faceta orientada a objetos. La mayoría de los lenguajes de OE abordan la cuestión de dónde tratar las operaciones que no dependen del estado del objeto y que en realidad no necesitan el objeto.

En algunos idiomas, como Java, las restricciones de idioma obligan a que todo esté en una clase, por lo que todo se convierte en una función miembro estática (por ejemplo, clases con utilidades matemáticas o algoritmos).

En C++, para mantener la compatibilidad con C, puede declarar funciones de estilo C independientes o utilizar el estilo Java de miembros estáticos. Mi opinión personal es que es mejor, cuando sea posible, usar el estilo OO y organizar las operaciones en torno a un concepto central.

Sin embargo, C++ proporciona las facilidades de espacios de nombres y a menudo se usa de la misma manera que una clase en esas situaciones: agrupar un grupo de elementos independientes donde cada elemento tiene el nombre de "espacio de nombres". Como otros señalan, muchas funciones de biblioteca estándar de C++ se ubican de esta manera. Mi opinión es que esto es muy parecido a usar una clase en Java. Sin embargo, otros argumentarían que Java usa clases porque no tiene espacios de nombres. Siempre que use uno u otro (en lugar de una función flotante independiente no espaciada) generalmente estará bien.

+1

Como de costumbre, sus observaciones sobre la práctica de C++ son incorrectas. C++ no "prefiere" las clases. –

+4

@Neil: C++ generalmente se enseña para la programación orientada a objetos, especialmente ahora que C se ha actualizado con muchas cosas para que sea más útil. Todavía diría que OOP es preferible. Pero realmente no tienes que ser tan idiota al respecto. – Uri

+2

Neil, supongo que Uri quería decir que los programadores de C++ * prefieren las clases, lo cual es cierto en mi experiencia (aunque subjetivo). – ChrisW

4

No es una mala práctica. Lo mejor de C++ es que te permite programar en muchos estilos. Esto le da al lenguaje una gran flexibilidad y utilidad, pero posiblemente hace que aprender sea más complicado que otros lenguajes que le obligan a escribir código en un estilo particular.

Si tiene un programa pequeño, puede escribirlo en una función, posiblemente usando un par de goto para el flujo de código.

Cuando creces, dividir el código en funciones ayuda a organizar las cosas.

Más grande aún, y las clases son generalmente una buena forma de agrupar funciones relacionadas que funcionan en un cierto conjunto de datos.

Aún más grande, los espacios de nombres ayudan.

A veces, sin embargo, es más fácil escribir una función para hacer algo. Este es a menudo el caso donde se escribe una función que solo funciona en tipos primitivos (como int). int no tiene una clase, por lo que si desea escribir una función printInt(), puede hacerlo de forma independiente. Además, si una función funciona en objetos de múltiples clases, pero en realidad no pertenece a una clase ni a la otra, podría tener sentido como una función independiente. Esto sucede mucho cuando escribe operadores, como definir menos que para poder comparar objetos de dos clases diferentes. O bien, si una función se puede escribir en términos de métodos públicos de una clase, y no necesita acceder directamente a los datos de la clase, algunas personas prefieren escribir eso como una función independiente.

Pero, en realidad, la elección es suya. Cualquier cosa que sea más simple de hacer para resolver su problema es lo mejor.

Puede iniciar un programa como solo unas pocas funciones y luego decidir que algunas están relacionadas y refactorizarlas en una clase. Pero, si las otras funciones independientes no encajan naturalmente en una clase, no es necesario forzarlas en una.

0

Soy bastante nuevo en C++ y he visto un montón de código que tiene definiciones de métodos en los archivos de encabezado y no declaran el archivo de encabezado como una clase.

Permite aclarar cosas.

definiciones de métodos en los archivos de cabecera

Esto significa algo como esto: archivo "A.h":

class A { 
void method(){/*blah blah*/} //definition of a method 
}; 

¿Es esto lo que quería decir?

Más tarde dices "declarar el archivo de encabezado". No hay ningún mecanismo para DECLARAR un archivo en C++. Un archivo puede ser INCLUIDO por witing #include "filename.h". Si hace esto, el contenido del archivo de encabezado se copiará y pegará en cualquier lugar donde tenga la línea anterior antes de que se compile cualquier cosa.

Quiere decir que todas las definiciones están en la definición de la clase (no en cualquier lugar de A.h FILE, sino específicamente en la clase A, que está limitada por 'clase A {' y '};'). La implicación de tener método definición en la definición de clase es que el método será 'inline' (esta es la palabra clave C++), lo que significa que el cuerpo del método se pegará cada vez que hay una llamada a la misma.Esto es:

  • buena, ya que el mecanismo de llamada a la función ya no ralentiza la ejecución
  • malo si la función es más largo que una declaración corta, porque el tamaño del código ejecutable crece mal

Las cosas son diferentes para las plantillas como alguien antes mencionado, pero para ellas hay una manera de definir métodos tales que no están en línea, sino que están en el archivo de encabezado (deben estar en los encabezados). Estas definiciones tienen que estar fuera de la definición de la clase de todos modos.

Cuestiones relacionadas