Як реалізувати функції статичного класу у файлі * .cpp?


125

Чи можливо реалізувати staticфункції члена класу у файлі * .cpp замість того, щоб це робити у файлі заголовка?

Чи всі staticфункції завжди inline?


4
Чи можете ви пояснити, чому ви "CANNOT" реалізуєте функцію пам'яті статичного класу у вашому файлі cpp? будь-яка помилка? Зазвичай це обмеження щодо того, де ви реалізуєте таку функцію.
зимаTTr

7
@winterTTr, питання, ймовірно, виникло тому, що більшість прикладів / навчальних посібників в Інтернеті не представляють окремого прикладу реалізації, а замість того, щоб оголосити та визначити його у заголовку. Принаймні перші шість звернень у моїй улюбленій пошуковій системі для "C ++ статичної функції члена" - все це робиться таким чином і не пояснює, як ви реалізуєте це в окремих файлах для початківця.
кробар

7
Коли ви реалізуєте, не повторюйте staticключове слово. Пишіть staticключове слово лише у визначенні класу у файлі заголовка
SomethingSomething

@crobar, ви праві, що існує дефіцит багатофайлових прикладів. Я намагався це зрозуміти, тому вирішив поділитися наступним:
Дон Маклахлан

Відповіді:


153

Це є.

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

Вони не завжди вбудовані, ні, але компілятор може зробити їх.


47

Спробуйте це:

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

Щоб дізнатися більше про те, як c ++ обробляє статичні функції, відвідайте: Чи копіюються функції статичного члена в c ++ у декількох одиницях перекладу?


2

Так, ви можете визначити статичні функції членів у файлі * .cpp. Якщо ви визначите це в заголовку, компілятор за замовчуванням вважатиме його як вбудований. Однак це не означає, що окремі копії функції статичного члена будуть існувати у виконуваному файлі. Будь ласка, слідкуйте за цим повідомленням, щоб дізнатись більше про це: Чи копіюються статичні функції членів у c ++ у декількох одиницях перекладу?


Якщо визначити його в тілі класу, він автоматично буде за замовчуванням. Якщо він знаходиться в заголовку поза тілом класу, його краще позначити inlineабо, templateабо ви отримаєте кілька помилок визначення від лінкера.
Бен Войгт

2

У своєму заголовковому файлі скажіть foo.h

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

У вашому файлі реалізації скажіть foo.cpp

#include "foo.h"

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

Дуже важливо

Просто переконайтеся, що ви не використовуєте статичне ключове слово у своєму підписі методу, коли ви реалізуєте статичну функцію у вашому файлі реалізації.

Щасти


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Директива буквально означає «копіювати всі дані в цьому файлі в цьому місці.» Отже, коли ви включаєте файл заголовка, він текстово знаходиться в кодовому файлі, і все, що в ньому буде, буде давати або приймати дію інших директив або макрозамінників, коли файл коду (тепер його називають блоком компіляції або блоком перекладу ) передається з модуля препроцесора в модуль компілятора.

Що означає, що декларація та визначення функції вашого статичного члена справді були в одному файлі весь час ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.