* .Cpp dosyasında statik sınıf üyesi işlevleri nasıl uygulanır?


125

staticSınıf üyesi işlevlerini başlık dosyasında yapmak yerine * .cpp dosyasında uygulamak mümkün müdür ?

Tüm staticişlevler her zaman inlinemıdır?


4
Cpp dosyanıza statik sınıf üye işlevini neden "YAPAMAZSINIZ" açıklayabilir misiniz? herhangi bir hata? Genellikle böyle bir işlevi nerede uyguladığınızla ilgili bir sınırlama yoktur.
winterTTr

7
@winterTTr, Bu soru büyük olasılıkla web'deki çoğu örnek / öğreticinin ayrı bir uygulama örneği sunmaması, bunun yerine başlıkta bildirip tanımlaması nedeniyle ortaya çıktı. "C ++ statik üye işlevi" için en sevdiğim arama motorundaki en azından ilk altı vuruş bunu bu şekilde yapıyor ve acemi bir kullanıcı için bunu ayrı dosyalarda nasıl uyguladığınızı açıklamıyor.
crobar

8
Uyguladığınızda, staticanahtar kelimeyi tekrar etmeyin . Yazın staticsadece başlık dosyasına sınıf tanımında anahtar kelime
SomethingSomething

@crobar, haklısınız, çoklu dosya örneklerinin yetersizliği var. Bunu
anlamakta zorlandım

Yanıtlar:


154

Bu.

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

Her zaman satır içi değillerdir, hayır, ancak derleyici bunları yapabilir.


47

Bunu dene:

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 ++ 'nın statik işlevleri nasıl işlediği hakkında daha fazla bilgi için şu adresi ziyaret edin: c ++' daki statik üye işlevler birden çok çeviri biriminde kopyalanır mı?


2

Evet, * .cpp dosyasında statik üye fonksiyonları tanımlayabilirsiniz. Bunu başlıkta tanımlarsanız, derleyici varsayılan olarak onu satır içi olarak değerlendirecektir. Ancak bu, çalıştırılabilir dosyada statik üye işlevinin ayrı kopyalarının bulunacağı anlamına gelmez. Bu konuda daha fazla bilgi edinmek için lütfen bu gönderiyi takip edin: c ++ 'daki statik üye fonksiyonları birden çok çeviri birimine mi kopyalanır?


Bunu sınıf gövdesinde tanımlarsanız, otomatik olarak varsayılan olacaktır. O sınıf vücut dışında başlığında ise, ya daha iyi işaretlenecektir vardı inlineya templateya da bağlayıcı birden fazla tanım hataları alırsınız.
Ben Voigt

2

Başlık dosyanızda foo.h deyin

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

Uygulama dosyanızda foo.cpp deyin

#include "foo.h"

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

Çok önemli

Uygulama dosyanızda statik işlevi uygularken, yöntem imzanızda static anahtar sözcüğünü kullanmadığınızdan emin olun.

İyi şanslar


1

@crobar, çoklu dosya örneklerinin yetersiz olduğu konusunda haklısın, bu yüzden başkalarına yardımcı olması umuduyla aşağıdakileri paylaşmaya karar verdim:

::::::::::::::
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

#includeDirektif kelimenin tam anlamıyla "Bu noktaya o dosyadaki tüm verileri kopyalamak" anlamına gelir. Eğer başlık dosyasını eklediğinizde Yani, kod dosya içinde metin olarak, ve her şey orada olacak içinde, vermek veya kod dosyası (şimdi adı verilen diğer direktifler veya makro değiştirmeler, etkisini almak derleme birimi veya çeviri birimi olan) önişlemci modülünden derleyici modülüne devredildi.

Bu, statik üye işlevinizin bildirimi ve tanımının gerçekten aynı dosyada olduğu anlamına gelir ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.