¿Cómo implementar funciones miembro de clase estática en el archivo * .cpp?

125

¿Es posible implementar staticfunciones de miembro de clase en el archivo * .cpp en lugar de hacerlo en el archivo de encabezado?

¿Son todas las staticfunciones siempre inline?

BartoszKP
fuente
44
¿Podría explicar por qué "NO PUEDE" implementar la función miembro de clase estática en su archivo cpp? algun error? Por lo general, no hay limitación sobre dónde implementa dicha función.
winterTTr
77
@winterTTr, la pregunta probablemente surgió porque la mayoría de los ejemplos / tutoriales en la web no presentan un ejemplo de implementación por separado, sino que lo declaran y definen en el encabezado. Al menos los primeros seis resultados en mi motor de búsqueda favorito para la "función miembro estática C ++" lo hacen de esta manera y no explican cómo implementarlo en archivos separados para un novato.
crobar
77
Cuando implemente, no repita la staticpalabra clave. Escriba la staticpalabra clave solo en la definición de clase en el archivo de encabezado
SomethingSomething
@crobar, tiene razón en que hay una escasez de ejemplos de varios archivos. Luché por resolver esto, así que decidí compartir lo siguiente:
Don Mclachlan

Respuestas:

153

Es.

test.hpp:

class A {
public:
    static int a(int i);
};

test.cpp:

#include <iostream>
#include "test.hpp"


int A::a(int i) {
    return i + 2;
}

using namespace std;
int main() {
    cout << A::a(4) << endl;
}

No siempre están en línea, no, pero el compilador puede hacerlos.

CromTheDestroyer
fuente
47

Prueba esto:

header.hxx:

class CFoo
{
public: 
    static bool IsThisThingOn();
};

class.cxx:

#include "header.hxx"
bool CFoo::IsThisThingOn() // note: no static keyword here
{
    return true;
}
paulcam
fuente
9

helper.hxx

class helper
{
 public: 
   static void fn1 () 
   { /* defined in header itself */ }

   /* fn2 defined in src file helper.cxx */
   static void fn2(); 
};

helper.cxx

#include "helper.hxx"
void helper::fn2()
{
  /* fn2 defined in helper.cxx */
  /* do something */
}

A.cxx

#include "helper.hxx"
A::foo() {
  helper::fn1(); 
  helper::fn2();
}

Para saber más sobre cómo c ++ maneja las funciones estáticas, visite: ¿Las funciones miembro estáticas en c ++ se copian en múltiples unidades de traducción?

Rocas Rizz
fuente
2

Sí, puede definir funciones miembro estáticas en el archivo * .cpp. Si lo define en el encabezado, el compilador lo tratará por defecto como en línea. Sin embargo, no significa que existan copias separadas de la función miembro estática en el ejecutable. Siga esta publicación para obtener más información al respecto: ¿Las funciones miembro estáticas en c ++ se copian en varias unidades de traducción?

cppcoder
fuente
Si lo define en el cuerpo de la clase, será automáticamente predeterminado. Si está en el encabezado fuera del cuerpo de la clase, será mejor que se marque, inlineo templateobtendrá múltiples errores de definición del enlazador.
Ben Voigt
2

En tu archivo de encabezado di foo.h

class Foo{
    public:
        static void someFunction(params..);
    // other stuff
}

En su archivo de implementación, diga foo.cpp

#include "foo.h"

void Foo::someFunction(params..){
    // Implementation of someFunction
}

Muy importante

Solo asegúrese de no usar la palabra clave estática en la firma de su método cuando implemente la función estática en su archivo de implementación.

Buena suerte

Sr. Suryaa Jha
fuente
1

@crobar, tiene razón en que hay una escasez de ejemplos de varios archivos, así que decidí compartir lo siguiente con la esperanza de que ayude a otros:

::::::::::::::
main.cpp
::::::::::::::

#include <iostream>

#include "UseSomething.h"
#include "Something.h"

int main()
{
    UseSomething y;
    std::cout << y.getValue() << '\n';
}

::::::::::::::
Something.h
::::::::::::::

#ifndef SOMETHING_H_
#define SOMETHING_H_

class Something
{
private:
    static int s_value;
public:
    static int getValue() { return s_value; } // static member function
};
#endif

::::::::::::::
Something.cpp
::::::::::::::

#include "Something.h"

int Something::s_value = 1; // initializer

::::::::::::::
UseSomething.h
::::::::::::::

#ifndef USESOMETHING_H_
#define USESOMETHING_H_

class UseSomething
{
public:
    int getValue();
};

#endif

::::::::::::::
UseSomething.cpp
::::::::::::::

#include "UseSomething.h"
#include "Something.h"

int UseSomething::getValue()
{
    return(Something::getValue());
}
Don mclachlan
fuente
0

La #includedirectiva literalmente significa "copiar todos los datos en ese archivo a este lugar". Entonces, cuando incluye el archivo de encabezado, está textualmente dentro del archivo de código, y todo lo que contenga estará allí, más o menos el efecto de otras directivas o reemplazos de macro, cuando el archivo de código (ahora llamado unidad de compilación o unidad de traducción ) está entregado desde el módulo preprocesador al módulo compilador.

Lo que significa que la declaración y la definición de su función miembro estática estuvieron realmente en el mismo archivo todo el tiempo ...

Blair Houghton
fuente