2009-08-25 14 views
7

Nie powiodło się połączenie dwóch plików po usunięciu słowa kluczowego "statyczne", więc jest w porządku. Testowane za pomocą g ++. Sprawdź przy pomocy pliku readelf, czy element statyczny wydaje się wyeksportowany jako globalny symbol obiektu ... Myślę, że powinien to być lokalny obiekt ...?wiele definicji dla statycznego członka?

static1.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

static2.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void second() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

z informacją o błędzie:

/tmp/ccIdHsDm.o:(.bss+0x0): stwardnienie definicja `StaticClass :: a”

Odpowiedz

16

Wydaje się, że starasz się mieć lokalne zajęcia każdego pliku źródłowego, o tej samej nazwie. W C++ można upakować lokalnych klas w przestrzeni nazw anonimowego:

namespace { 
class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
} // close namespace 

void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 
+0

@Ropez: działa dobrze. Dzięki :) –

+0

Czuję się źle ze względu na stan rzeczy, ponieważ odpowiedź ropez "wydaje się, że dała ci rozwiązanie, którego szukałeś. nie krępuj się przesuwać znacznik wyboru do swojej :) :) +1 dla niego. –

+0

@Litb, obaj macie rację :) Wyjaśniłeś więcej. –

0

StaticClass potrzebuje miejsca do przechowywania a, statyczną zmienną, która będzie współdzielony przez wszystkie instancje klasy - istnieją dwie linie, które to zrobić, po jednym w każdym pliku. Usunięcie jednego z nich naprawi błąd łącznika.

9

Poniżej znajduje się definicja statycznego członka danych. Musi wystąpić tylko w jednym pliku, który jest skompilowany, a następnie połączony.

int StaticClass::a = 0; 

Jeśli masz wiele takich definicji, to tak jakby trzeba było wiele funkcji zwanych first. Będą się ścierać, a linker złoży skargę.

Myślę, że mylnie członkowie statycznych ze statycznym zastosowane do przestrzeni nazw zmiennych zakresu. Na poziomie przestrzeni nazw static podaje zmienną lub referencyjny wewnętrzny link. Ale na poziomie zakresu klasy (gdy zostanie zastosowany do elementu), stanie się statycznym elementem - takim, który jest powiązany z klasą, a nie z każdym obiektem osobno. To nie ma już nic wspólnego z C "statycznym".

+0

Problemem jest to, że myślę, że łącznik powinien wiedzieć, że odwołuje się zmienną w swoim lokalnym pliku wynikowego, ponieważ jest to zmienna lokalna statyczny, a nie globalny statyczny jeden. –

+0

to nie jest lokalne ani globalne. to jest członek klasy. http://pl.wikipedia.org/wiki/Klasa_zmienna –

+2

@arsane, Jeśli chcesz mieć klasę lokalizacji, musisz umieścić ją w anonimowym obszarze nazw.Podczas pisania, StaticClass z static1.cpp jest tą samą klasą, co StaticClass z static2.cpp. Zanim powiemy, że klasy nie są zdefiniowane w nagłówku, nie zapominaj, że makroprocesor działa poprzez włączenie tekstowe. – AProgrammer

2

Oświadczenie

int StaticClass::a = 0; 

rzeczywiście alokuje pamięć dla zmiennej, dlatego powinien on być napisany tylko raz.

Co do uwagi, jesteś prawdopodobnie mylące dwa różne zastosowania kluczowych static. W języku C statycznym określenie "wykorzystanie wewnętrznego powiązania" oznacza, że ​​nazwa zmiennej lub funkcji nie byłaby widoczna poza jednostką tłumaczeniową, w której została zdefiniowana.

W klasach static służy do definiowania elementów klas, czyli zmiennych lub metod, które nie odnoszą się do konkretnego wystąpienia klasy. W tym przypadku miejsce na zmienną statyczną musi zostać przydzielone gdzieś (ponieważ nie jest częścią żadnej instancji), ale tylko w jednym miejscu.

Powiązane problemy