Как реализовать статические функции-члены класса в файле *.cpp?

Возможно ли реализовать функции класса static класса в файле *.cpp вместо того, чтобы делать это в файле заголовка?

Все функции static всегда inline?

Ответ 1

Это.

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

Они не всегда встроены, нет, но компилятор может их создать.

Ответ 2

Попробуйте следующее:

header.hxx:

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

class.cxx:

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

Ответ 3

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

Чтобы узнать больше о том, как С++ обрабатывает статические функции, посетите: Являются ли статические функции-члены в С++ скопированы в несколько единиц перевода?

Ответ 4

Да, вы можете определить статические функции-члены в файле *.cpp. Если вы определяете его в заголовке, компилятор будет по умолчанию рассматривать его как встроенный. Однако это не означает, что в исполняемом файле будут существовать отдельные копии статической функции-члена. Пожалуйста, следуйте этому сообщению, чтобы узнать больше об этом: Являются ли статические функции-члены в С++ скопированы в несколько единиц перевода?

Ответ 5

@crobar, вы правы, что есть недостаток примеров с несколькими файлами, поэтому я решил поделиться следующим в надежде, что он поможет другим:

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

Ответ 7

Директива #include буквально означает "скопировать все данные в этом файле на это место". Поэтому, когда вы включаете заголовочный файл, он текстовым образом находится в файле кода, и все в нем будет присутствовать, давать или брать в действие другие директивы или замены макросов, когда файл кода (теперь называемый единицей компиляции или единиц перевода) передается от модуля препроцессора к модулю компилятора.

Это означает, что декларация и определение вашей статической функции-члена действительно находились в одном файле...