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

125

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

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

BartoszKP
источник
4
Не могли бы вы объяснить, почему вы «НЕ МОЖЕТЕ» реализовать функцию члена статического класса в вашем файле cpp? какая-нибудь ошибка? Обычно нет ограничений относительно того, где вы реализуете такую ​​функцию.
winterTTr
7
@winterTTr, вопрос, вероятно, возник из-за того, что большинство примеров / руководств в сети не представляют отдельный пример реализации, вместо этого объявляя и определяя его в заголовке. По крайней мере, первые шесть совпадений в моей любимой поисковой системе для "статической функции-члена C ++" делают это таким образом и не объясняют, как вы реализуете ее в отдельных файлах для новичков.
Crobar
8
При реализации не повторяйте staticключевое слово. Пишите staticключевое слово только в определении класса в заголовочном файле
SomethingSomething
@crobar, вы правы, что многофайловых примеров мало. Я изо всех сил пытался понять это, поэтому я решил поделиться следующим:
Дон Маклахлан

Ответы:

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

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

CromTheDestroyer
источник
47

Попробуй это:

header.hxx:

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

class.cxx:

#include "header.hxx"
bool CFoo::IsThisThingOn() // note: no static keyword here
{
    return true;
}
paulcam
источник
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();
}

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

Ризз Рокс
источник
2

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

cppcoder
источник
Если вы определите его в теле класса, он автоматически станет значением по умолчанию. Если это в заголовке вне тела класса, то лучше быть маркированы как inlineили , templateили вы получите несколько ошибок определения из компоновщика.
Ben Voigt
2

В вашем заголовочном файле скажите foo.h

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

В вашем файле реализации скажите foo.cpp

#include "foo.h"

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

Очень важно

Просто убедитесь, что вы не используете ключевое слово static в сигнатуре метода при реализации статической функции в файле реализации.

Удачи

Г-н Сурьяа Джа
источник
1

@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());
}
Дон Маклахлан
источник
0

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

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

Блэр Хоутон
источник