Come implementare le funzioni membro della classe statica nel file * .cpp?


125

È possibile implementare staticle funzioni dei membri della classe nel file * .cpp invece di farlo nel file di intestazione?

Tutte le staticfunzioni sono sempre inline?


4
Puoi spiegare perché "NON PUOI" implementare la funzione di memeber di classi statiche nel tuo file cpp? qualche errore? Di solito non è una limitazione su dove si implementa tale funzione.
WinterTTr

7
@winterTTr, La domanda probabilmente è sorta perché la maggior parte degli esempi / tutorial sul Web non presenta un esempio di implementazione separato, ma lo dichiara e lo definisce nell'intestazione. Almeno i primi sei risultati nel mio motore di ricerca preferito per la "funzione membro statica C ++" lo fanno tutti in questo modo e non spiegano come implementarlo in file separati per un principiante.
Crobar

8
Quando implementi, non ripetere la staticparola chiave. Scrivi la staticparola chiave solo nella definizione della classe nel file di intestazione
SomethingSomething

@crobar, hai ragione sul fatto che mancano gli esempi multi-file. Ho faticato a capirlo, quindi ho deciso di condividere quanto segue:
Don Mclachlan

Risposte:


154

È.

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;
}

Non sono sempre in linea, no, ma il compilatore può crearli.


47

Prova questo:

header.hxx:

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

class.cxx:

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

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();
}

Per saperne di più su come c ++ gestisce le funzioni statiche, visitare: Le funzioni membro statiche in c ++ vengono copiate in più unità di traduzione?


2

Sì, puoi definire funzioni membro statiche nel file * .cpp. Se lo definisci nell'intestazione, il compilatore lo tratterà per impostazione predefinita come inline. Tuttavia, non significa che nell'eseguibile saranno presenti copie separate della funzione membro statica. Segui questo post per saperne di più: Le funzioni membro statiche in c ++ vengono copiate in più unità di traduzione?


Se lo definisci nel corpo della classe, sarà automaticamente predefinito. Se si trova nell'intestazione al di fuori del corpo della classe, è meglio che sia contrassegnato inlineo templateoppure riceverai più errori di definizione dal linker.
Ben Voigt

2

Nel tuo file di intestazione dì foo.h

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

Nel tuo file di implementazione dì foo.cpp

#include "foo.h"

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

Molto importante

Assicurati solo di non utilizzare la parola chiave static nella firma del metodo quando stai implementando la funzione static nel tuo file di implementazione.

In bocca al lupo


1

@crobar, hai ragione sul fatto che mancano esempi di più file, quindi ho deciso di condividere quanto segue nella speranza che aiuti gli altri:

::::::::::::::
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());
}


0

La #includedirettiva significa letteralmente "copia tutti i dati in quel file in questo punto". Quindi, quando includi il file di intestazione, è testualmente all'interno del file di codice e tutto ciò che contiene sarà lì, darà o avrà l'effetto di altre direttive o sostituzioni di macro, quando il file di codice (ora chiamato unità di compilazione o unità di traduzione ) è trasferito dal modulo del preprocessore al modulo del compilatore.

Il che significa che la dichiarazione e la definizione della tua funzione membro statica erano davvero nello stesso file da sempre ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.