DaQRT napisał(a)
static int b =13;
tak w ogole to to juz samo w sobie jest niepoprawne, inicjalizowac w definicji klasy mozna jedynie const statici
MarekR22: niestety, to co proponujesz nie ruszy. po drobnych poprawkach:
-sh-3.00# cat y.cpp;g++ y.cpp;
#include <iostream>
#include <vector>
class TMojaTabInt : public std::vector<int>
{
public:
TMojaTabInt(int size) : std::vector<int>(size)
{
// tu inicjujesz zawartość tablicy np
at(0) = 3;
for(int i=1;i<size;i++)
at(i) = at(i-1)/4+(i-80)/4;
}
};
class A {
public:
static int b =13; //<-- o tym pisalem powyzej
static TMojaTabInt c(666); // poprawka twojej //<---tu jest blad
};
int main()
{ std::cout << A::c[5] << std::endl;
}
wynik kompilacji:
-sh-3.00# g++ y.cpp
y.cpp:18: error: ISO C++ forbids in-class initialization of non-const static
member b' y.cpp:19: error: invalid data member initialization y.cpp:19: error: (use
=' to initialize static data members)
Twoj blad jest banalny: nie masz prawa w ten sposob "wywolac" konstruktora.
poprawny kod (przy okazji wciagnalem definicje klasy do srodka, zeby nie smiecic symbolami w namespace'ie:
#include <iostream>
#include <vector>
class A {
public:
struct _c : std::vector<int>
{
_c() : std::vector<int>(666) //tutaj podajesz rozmiar 'tablicy'
{
at(0) = 3;
for(int i=1;i<size();i++)
at(i) = at(i-1)/4+(i-80)/4;
}
} static c;
};
A::_c A::c; //wymagana loklaizaja pola statycznego
//przy okazji sideeffect: inicjalizacja poprzez konstruktor. juz bez parametrow
//one sa wyryte w kodzie klasy na sztywno, tak jak by to bylo z rozmiarem tablicy
int main()
{
std::cout << A::c[5] << std::endl;
}
a wracajac do oryginalnego problemu - jak zainicjalizowac konkretnie TABLICE, nie vector:
#include <iostream>
class A {
public:
static int b;
static int c[666];
private:
struct _si //'emulator' statycznego konstruktora, wystarczy jeden per klasa
{ _si()
{
b = 10;
c[0] = 3;
for(int i=1;i<666;i++)
c[i] = c[i-1]/4+(i-80)/4;
}
} static _init;
};
int A::c[]; //wymagana lokalizacja pola statycznego, bez wymiarow, one sa wyryte w definicji klasy
int A::b; //kazde pole statyczne bedace non-const wymaga lokalizacji
A::_si A::_init; //a wiec - inicjalizator rowniez!
int main()
{
std::cout << A::c[5] << std::endl;
}
ten sposob pozwala na zainicjalizowanie wszystkich statykow w klasie w dowolny sposob i bez pisania nowych, specyficznych typow dla kazdego statica (np. pieciu subklas vector<int> bo mamy piec roznych tablic do zainicjalizowania)
uwagi:
-
takie statyczne inicjalizatory jak zaproponowalem na koncu maja jedna "wade": zajmuja jeden bajt. koszt jest per-klasa nie per-pole, wiec majac 10 klas z taka inicjalizacja i 100 pol statycznych w kazdej z tych klas, tracisz 10 bajtow. dzieje sie tak poniewaz KAZDE pole klasy musi byc jednoznacznie adresowalne. struktura _c nie ma wlasnej zawartosci, teoretycznie wazy wiec 0B. jednakze, jako ze istnieje pole, to musi miec ono wlasny adres, wiec podczas kompilacji struktura ta uzyskuje rozmiar najmniejszy mozliwy -- czyli 1 bajt. a ze pole samo w sobie jest static.. wiec ten jeden bajt jest 'zajety' na caly czas dzialania procesu
-
rozwiazanie wczesniejsze, z implementacja wlasnego subtypu zmiennej (tak jak u Marka albo w moim przykladzie z struct _c) ma tu teoretyczna przewage - nie ma tego ukrytego kosztu. jest natomiast.. koszt klasy vector. na g++ sizeof(vector<int>) to 12 bajtow. placony per-klasa-i-pole. majac 10 klas i 100 tablic statycznych w kazdej z nich, tracisz 1210100 bajtow (nie mowiac o tym, ze dla kazdej musisz napisac odpowiedni typ danych)
polecam wiec rozwiazanie ostatnie. "moje", moze wyglada troche brzydziej, ale sa same plusy. i pozwala inicjalizowac/wyliczac np. double, czego rozwiazaniem poprzednim raczej sie nie zrobi szybko (pisac typ class Double..?)