składnik statyczny klasy

0

Czy istnieje jakiś bardziej elegancki sposób na zainicjalizowanie składnika statycznego klasy. Chciałbym, żeby to był vector<string>, i żeby był składnikiem prywatnym. Nie wiem jedank w jaki sposob to zrobić. Bo jeśli umieszcze to w konstruktorze, to na darmo będę za każdym razem inicjalizował ten vector od nowa, co byłoby nieoptymalne (obiektów typu tej klasy będzie naprawdę sporo)... Co mi poradzicie ?

0

do skladnikow statycznych mozesz sie odwolywac uzywajac nie nazwe obiektu, choc to oczywiscie mozliwe :) ale nazwa klasy. nie wiem, czy taki skladnik nie istnieje gdy nie ma zadnego obiektu , to sprawdz, sprobuj zainicjowac przed otworzeniem czegokolwiek. ktoras ponizszycj form jast dobra:

nazwaklasy.skladnik:=bleble
nazwaklasy:=bleble

jazeli jest to prywatny skladnik, to moze za posrednictwem funkcji zaprzyjaznionej ?

0

Wiem o tym, ale nie moge wywołać na rzecz takiego obiektu, jego f-kcji składowej. Przy próbie takiego wywołania dostaję błąd :(

vector<string> OneLine::FormatCmds;
OneLine::FormatCmds.push_back("center");

Ten kod jest poza wszelkimi klamrami, bezopośredni po ciele klasy. W drugiej linijce dostaję błąd kompilacji - pisze że "oczekiwał konstruktora przy typie konwersji" (dokładnie jak to brzmi to wrzuce, jak wróce do domu).

0

np tak:

vector<string> OneLine::FormatCmds = vector<string>::vector(1, "center");
0

nie wiem czy ja dobrze rozumiem problem, ale z teog co wiem to zmienna statyczna jest inicjowana tylko jeden raz w czasie istnienia programu co zapewnia kompialator. nie ma wiec potrzeby kombinowac z zewnetrznymi funkcjami.

0

Przepraszam że tak długo nie odpowiadałem, ale dopiero teraz przysiadłem do tego "projektu".

Maker twój sposób działa tylko, jeśli chciałbym mieć vector z jednym elementem lub kilkoma takimi samymi elementami. Jednak ja chciałbym aby w innych indeksach mieć inne stringi z odp. formatami...

vixen03 też myślę, że nie ma sensu robić funkcji, którą i tak wywołam tylko raz.

Jak zrobic, żebym mógł mieć kilka napisów w tym vectorze [???]

0

no w tym wypadku to najlepij to tak rozwiazac:

class jakas
{
public:             
jakas()
{
if (!s)
{
s = new vector<string>;
s->push_back("jakis");
s->push_back("inny");
s->push_back("itd...");
}
}
~jakas()
{
if (s)
{
delete s;
s = NULL;
}
}			
private:
static vector<string> *s;
}; 
vector<string> *jakas::s = NULL;

BTW: jestem MAKER nie Marker i to wbij do swojej glowy w koncy bo juz nie pierwszy raz sie tak do mnie zwracasz a powoli staje sie to obrazliwe...

0

Wielkie dzięki Maker, teraz działa super :) Fajny sposób wymyśliłeś :)

// Przepraszam za pomyłkę w nicku, nie zamierzona oczywiście

0
DzieX napisał(a)

Czy istnieje sposób na zainicjalizowanie składnika statycznego klasy. jeśli umieszcze to w konstruktorze, to na darmo będę za każdym razem inicjalizował ten vector od nowa

zainicjujesz go tylko jeden jedyny raz w pierwszym wywolaniu konstruktora i bedzie on zainicjowany ta wartoscia do konca zycia programu. taki jest przeciez sens istnienia zmiennych statycznych

0

No właśnie miałem wątpliwości, bo moja inicjalizacja, to raczej taka "pseudo" inicjalizacja. Chodzi o to, że wywołuję metodę push_back() a ona przecież dorzuca do vectora na koniec jakąś wartość... Zreszta zaraz to napiszę i obczaję jak to się właściwie dzieje :P

0
vixen03 napisał(a)
DzieX napisał(a)

Czy istnieje sposób na zainicjalizowanie składnika statycznego klasy. jeśli umieszcze to w konstruktorze, to na darmo będę za każdym razem inicjalizował ten vector od nowa

zainicjujesz go tylko jeden jedyny raz w pierwszym wywolaniu konstruktora i bedzie on zainicjowany ta wartoscia do konca zycia programu. taki jest przeciez sens istnienia zmiennych statycznych

wiesz wszystko jak wszystko ale raczej zeby inicjalizacja byla w konstruktorze stala musisz dac odpowiedni warunek np moj sposob przedstawia wykorzystanei wlasciwosci zmiennych typu static w klasie to co napisales raczej to maslo maslane ;)

0

Sposób z "new" podany przez Makera jest dobry, ale ma istotną wadę:
Przy każdym odwołaniu do obiektu trzeba sprawdzić, czy wskaźnik nie jest równy 0. Ponadto nie ma możliwości wywołania destruktora.

Oto sposób pozbawiony tych wad:


class jakas_init;

// jakas.h: 
class jakas
{
    friend class jakas_init;
    private:
       static vector<string> *s;
}; 

class jakas_init
{
    public:
        jakas_init() 
        { 
            if (!(counter++)) {
                 jakas::s = new vector<string>;
                 jakas::s->push_back(...);
                 jakas::s->push_back(...);
            }
        }            

        ~jakas_init() 
        {
           if (!(--counter)) {
                 delete jakas::s;
           }

       } 
    private:
       static int counter;
};

namespace {
   jakas_init j;
}

// jakas.cpp:
#include "jakas.h"
int jakas_init::counter = 0;
vector<string> *jakas::s = 0;  // NIE NULL, bo piszemy w C++!

Ten sposob gwarantuje, że gdziekolwiek będziemy chcieli skorzystać z klasy "jakas", zmienna "s" będzie zainicjowana, a wektor wypełniony. BEZ żadnego narzutu przy każdym dostępie. Po wyjściu z programu zostanie również wywołany destruktor wektora.

0

Hmmm, widzę że wywołałem burzliwą dyskujsję :P

Co do ostatniej wypowiedzi to poradziłem sobie bez operatora new:

class OneLine {
	//friend ostream &operator<<(ostream &out, OneLine &obj);
	//friend istream &operator>>(istream &in, OneLine &obj);

	static vector<string> 	FormatCmds;
	
	void 			CalcSize();
	void			FormatInterpret();
	
public:
	
	OneLine(): size(0) {
		if(FormatCmds.empty()) {
			FormatCmds.push_back("center");
			FormatCmds.push_back("color");
			FormatCmds.push_back("left");
		}
		
	}
	OneLine(string str): line(str), size( line.size() ) {
		OneLine();
	}
	
	
	string			line;
	unsigned		size;
};

vector<string> OneLine::FormatCmds;

Mam pewność, że wektor zawsze będzie wypełniony, bo gdy będzie powstawal pierwszy obiekt, to nastąp inicjalizacja. Poza tym nie będe mógł się odwołać do obektu FormatCmds, za pośrednicwem nazwy klasy, gdyż jest on po prostu prywatny.

0

to jeszcze zainteresuj sie funkcjami statycznymi, czyli takimi, ktore maja dostep tylko do skladowych statycznych. moze przydadza sie pozniej.

0

Hehe, wiem :P Jestem na trochę wyższym poziomie, ale vectora nigdy nie miałem jako składowej statycznej :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1