Soy un desarrollador de JAVA que está tratando de aprender C ++, pero realmente no sé cuál es la mejor práctica para las declaraciones de funciones estándar.
En la clase:
class Clazz
{
public:
void Fun1()
{
//do something
}
}
O afuera:
class Clazz
{
public:
void Fun1();
}
Clazz::Fun1(){
// Do something
}
Tengo la sensación de que el segundo puede ser menos legible ...
.cpp
archivo separado .inline
.inline
solo relaja la regla de una definición, que es necesaria si se usa otra unidad de traducciónClazz
Respuestas:
C ++ está orientado a objetos, en el sentido de que apoya el paradigma orientado a objetos para el desarrollo de software.
Sin embargo, a diferencia de Java, C ++ no le obliga a agrupar las definiciones de funciones en clases: la forma estándar de C ++ para declarar una función es simplemente declarar una función, sin ninguna clase.
Si, en cambio, está hablando de declaración / definición de método, entonces la forma estándar es poner solo la declaración en un archivo de inclusión (normalmente llamado
.h
o.hpp
) y la definición en un archivo de implementación separado (normalmente llamado.cpp
o.cxx
). Estoy de acuerdo en que esto es algo molesto y requiere cierta duplicación, pero así es como se diseñó el lenguaje.Para experimentos rápidos y proyectos de un solo archivo, cualquier cosa funcionaría ... pero para proyectos más grandes, esta separación es algo que se requiere prácticamente.
Nota: Incluso si conoce Java, C ++ es un lenguaje completamente diferente ... y es un lenguaje que no se puede aprender experimentando. La razón es que es un lenguaje bastante complejo con muchas asimetrías y elecciones aparentemente ilógicas, y lo más importante, cuando comete un error, no hay "ángeles de error en tiempo de ejecución" para salvarlo como en Java ... pero en su lugar hay " demonios de comportamiento indefinido ".
La única forma razonable de aprender C ++ es leyendo ... no importa lo inteligente que sea, no hay forma de que pueda adivinar lo que decidió el comité (en realidad, ser inteligente es a veces incluso un problema porque la respuesta correcta es ilógica y una consecuencia de patrimonio.)
Simplemente elija uno o dos libros buenos y léalos de cabo a rabo.
fuente
El primero define su función miembro como una función en línea , mientras que el segundo no lo hace. La definición de la función en este caso reside en el propio encabezado.
La segunda implementación colocaría la definición de la función en el archivo cpp.
Ambos son semánticamente diferentes y no es solo una cuestión de estilo.
fuente
La definición de funciones es mejor fuera de la clase. De esa manera, su código puede permanecer seguro si es necesario. El archivo de encabezado solo debe dar declaraciones.
Suponga que alguien quiere usar su código, puede simplemente darle el archivo .hy el archivo .obj (obtenido después de la compilación) de su clase. No necesita el archivo .cpp para usar su código.
De esa manera, su implementación no será visible para nadie más.
fuente
El método "Dentro de la clase" (I) hace lo mismo que el método "Fuera de la clase" (O).
Sin embargo, (I) se puede usar cuando una clase solo se usa en un archivo (dentro de un archivo .cpp). (O) se usa cuando está en un archivo de encabezado. Los archivos cpp siempre se compilan. Los archivos de encabezado se compilan cuando usa #include "header.h".
Si usa (I) en un archivo de encabezado, la función (Fun1) se declarará cada vez que incluya #include "header.h". Esto puede llevar a declarar la misma función varias veces. Esto es más difícil de compilar e incluso puede provocar errores.
Ejemplo de uso correcto:
Archivo1: "Clazz.h"
//This file sets up the class with a prototype body. class Clazz { public: void Fun1();//This is a Fun1 Prototype. };
Archivo2: "Clazz.cpp"
#include "Clazz.h" //this file gives Fun1() (prototyped in the header) a body once. void Clazz::Fun1() { //Do stuff... }
Archivo3: "UseClazz.cpp"
#include "Clazz.h" //This file uses Fun1() but does not care where Fun1 was given a body. class MyClazz; MyClazz.Fun1();//This does Fun1, as prototyped in the header.
Archivo4: "AlsoUseClazz.cpp"
#include "Clazz.h" //This file uses Fun1() but does not care where Fun1 was given a body. class MyClazz2; MyClazz2.Fun1();//This does Fun1, as prototyped in the header.
Archivo5: "DoNotUseClazzHeader.cpp"
//here we do not include Clazz.h. So this is another scope. class Clazz { public: void Fun1() { //Do something else... } }; class MyClazz; //this is a totally different thing. MyClazz.Fun1(); //this does something else.
fuente
Clazz MyClazz
yClazz MyClazz2
?Las funciones miembro se pueden definir dentro de la definición de clase o por separado usando el operador de resolución de alcance, ::. La definición de una función miembro dentro de la definición de clase declara la función en línea, incluso si no usa el especificador en línea. Entonces, puede definir la función Volume () de la siguiente manera:
class Box { public: double length; double breadth; double height; double getVolume(void) { return length * breadth * height; } };
Si lo desea, puede definir la misma función fuera de la clase utilizando el operador de resolución de alcance, :: de la siguiente manera
double Box::getVolume(void) { return length * breadth * height; }
Aquí, el único punto importante es que tendría que usar el nombre de la clase justo antes de :: operator. Se llamará a una función miembro usando un operador de punto (.) En un objeto donde manipulará los datos relacionados con ese objeto solo de la siguiente manera:
(de: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm ), ambas formas son legales.
No soy un experto, pero creo que si pones solo una definición de clase en un archivo, entonces realmente no importa.
pero si aplica algo como clase interna, o tiene una definición de clase múltiple, la segunda sería difícil de leer y mantener.
fuente
El primero debe colocarse en el archivo de encabezado (donde reside la declaración de la clase). El segundo puede estar en cualquier lugar, ya sea el encabezado o, por lo general, un archivo fuente. En la práctica, puede poner pequeñas funciones en la declaración de la clase (que las declara implícitamente en línea, aunque es el compilador el que finalmente decide si estarán en línea o no). Sin embargo, la mayoría de las funciones tienen una declaración en el encabezado y la implementación en un archivo cpp, como en su segundo ejemplo. Y no, no veo ninguna razón por la que esto sea menos legible. Sin mencionar que podría dividir la implementación para un tipo en varios archivos cpp.
fuente
Una función que se define dentro de una clase se trata de forma predeterminada como una función en línea. Una simple razón por la que debería definir su función fuera:
Un constructor de la clase busca funciones virtuales e inicializa un puntero virtual para apuntar al VTABLE apropiado o la tabla del método virtual , llama al constructor de la clase base e inicializa las variables de la clase actual, por lo que realmente funciona.
Las funciones en línea se utilizan cuando las funciones no son tan complicadas y evita la sobrecarga de la llamada a la función. (La sobrecarga incluye un salto y una ramificación en el nivel de hardware). Y como se describió anteriormente, el constructor no es tan simple de considerar como en línea.
fuente
Funciones en línea (funciones cuando las declaras en la clase) cada vez que las llamas se pegan en tu código de memoria principal. Mientras que cuando declaras la función fuera de la clase, cuando llamas a la función, proviene de la misma memoria. Por eso es mucho mejor.
fuente