deklaracja zmiennej z przypisaniem w klasie C++

0

Czy mógłby mi ktoś pomóc i wyjaśnić jak zainicjalizować zmienną np. typu double wewnątrz klasy? Przykładowo chciałbym mieć taką klasę:

class klasa{
double zmienna = 27.3; //inicjalizacja zmiennej w klasie (tak chyba nie można :/)
int a = 3;
int b = 0;
//...
public:
klasa(double x):zmienna(x) //tylko w razie potrzeby, żeby ta wartość była zmieniana konstruktorem
{}
}

Chodzi o to, że w klasie chciałbym mieć kilka konstruktorów, które będą wykorzystywane w zależności od celu i nie chcę w każdym z nich przypisywać wstępnej wartości...
Gdzieś kiedyś o tym czytałem (bodajże w Symfonii, której chwilowo nie mam), a nie mogę nigdzie w internecie znaleźć opisu powyższego problemu - czy może mi ktoś napisać lub wskazać opis z rozwiązaniem tego problemu?
z góry dzięki!

1
class klasa
{
    double zmienna;
//...
public:
    klasa(double x) : zmienna(x) {}
    klasa() : zmienna(27.3) {}
};
0
Azarien napisał(a)
class klasa
{
    double zmienna;
//...
public:
    klasa(double x) : zmienna(x) {}
    klasa() : zmienna(27.3) {}
};

Azarien dzięki, ale czy nie ma innego sposoby, żeby właśnie nie używać do tego konstruktorów, które chciałbym do czego innego wykorzystać :-)
to się jakoś poza klasą chyba robiło - ale zupełnie nie pamiętam a teraz by mi się przydało :(

0

To chyba było coś takiego, że deklarowało się ją poza klasą tj. np. tak:

class klasa{
double zmienna;
//...
};
klasa::zmienna = 27.3;

Czy może ktoś to potwierdzić i napisać czy jest jeszcze jakiś sposób etc?
Może ktoś się spotkał z opisem powyższego problemu gdzieś w internecie?

0
Misz napisał(a)

Chodzi o to, że w klasie chciałbym mieć kilka konstruktorów, które będą wykorzystywane w zależności od celu i nie chcę w każdym z nich przypisywać wstępnej wartości
to zrób sobie metodę np. init() i w niej inicjalizuj co tam chcesz.

0
class klasa{
double zmienna;
//...
};
klasa::zmienna = 27.3;

To jest źle, bo operatora :: w takim wypadku stosuje się do statycznych pól klasy. Po drugie to pole nie jest publiczne. Jak już chcesz inicjalizować zmienną poza klasą to:

class Klasa
{
    public:
        double zmienna;
};

// odwołanie:

(...)

Klasa obiekt;
obiekt.zmienna = 27.3;
0
xeo545x39 napisał(a)

To jest źle, bo operatora :: w takim wypadku stosuje się do statycznych pól klasy. Po drugie to pole nie jest publiczne. Jak już chcesz inicjalizować zmienną poza klasą to:

No tak, przeoczyłem słówko "public" :)
Ale mi chodzi właśnie o to, żeby zainicjalizować zmienną zanim klasa zostanie wywołana - tzn. żeby każdy obiekt, który zostanie zadeklarowany, żeby wstępnie miał zainicjalizowaną zmienną. Później oczywiście ta inicjalizacja powinna móc być zmieniona czyli jak stworzymy obiekt to tak jak Ty pokazałeś można nadać tej zmiennej inną wartość.
Mam nadzieję, że rozumiecie o co mi chodzi :)

Czyli innymi słowy chodzi mi o to, żeby po utworzeniu obiektu typu klasa ten obiekt miał już zainicjalizowaną zmienną, ale żeby nie używać do tego konstruktora

0

Konstruktora właśnie nie chcę używać bo jego chcę wykorzystać do innej zmiennej - szczególnie tego domniemanego. Chcę go również wiele razy przeładować ale nie chcę, żeby on się tym zajmował.
Na prawdę nie da się tego zrobić? Wydaje mi się, że w symfonii był o tym rozdział - ale ja jej chwilowo nie mam.
Teoretycznie mógłbym do tego zrobić kolejną klasę, która będzie miała również domniemany konstruktor i w którym przypiszę tą wartość, ale to trochę głupie, żeby robić klasę tylko po to, by móc to zrobić... W innych językach (w javie lub C# chyba jest taka możliwość, że w klasie się od razu deklaruje zmienne - a może się mylę? :/)
pozdrawiam

0

A proszę mi jeszcze powiedzieć czy jeśli tworzę klasę i deklaruję tam zmienne to czy zawsze będą one zainicjalizowane 0 lub 0-podobną wartością? Czy może się tak zdarzyć, że będą w niej "śmieci"?

0

Nie będą inicjalizowane, chyba że obiekt klasy jest zadeklarowany globalnie -- tu są takie same zasady jak dla typów prostych.

0

Pola typów wbudowanych będą śmieciami, dla reszty wywoła się konstruktor domyślny.

0

Czyli jak mam tak:

class klasa{
public:
int x;
double y;
bool z;
};
int main(){
klasa x;
cout << "to może być śmieć: " << x.x << endl; // tak?

???

0

Nadal nie podałeś żadnego powodu czemu nie miałby robić tego konstruktor. Przecież on może inicjalizować dowolną ilość zmiennych

0

Jeśli problemem jest to, że nie chcesz wielokrotnie powtarzać tych samych inicjalizacji w różnych konstruktorach to skorzystaj z tej rady:

tini napisał(a)
Misz napisał(a)

Chodzi o to, że w klasie chciałbym mieć kilka konstruktorów, które będą wykorzystywane w zależności od celu i nie chcę w każdym z nich przypisywać wstępnej wartości
to zrób sobie metodę np. init() i w niej inicjalizuj co tam chcesz.
czyli np.

class klasa {
	double zmienna;
	int a;
	int b;

	void init()
	{
		this->zmienna = 27.3;
		this->a = 3;
		this->b = 0;
	}

public:
	klasa()
	{
		this->init();
	}

	klasa(double x)
	{
		this->init();
		this->zmienna = x;
	}
};
0
adf88 napisał(a)

Jeśli problemem jest to, że nie chcesz wielokrotnie powtarzać tych samych inicjalizacji w różnych konstruktorach to skorzystaj z tej rady:

tini napisał(a)
Misz napisał(a)

Chodzi o to, że w klasie chciałbym mieć kilka konstruktorów, które będą wykorzystywane w zależności od celu i nie chcę w każdym z nich przypisywać wstępnej wartości
to zrób sobie metodę np. init() i w niej inicjalizuj co tam chcesz.
czyli np.

class klasa {
	double zmienna;
	int a;
	int b;

	void init()
	{
		this->zmienna = 27.3;
		this->a = 3;
		this->b = 0;
	}

public:
	klasa()
	{
		this->init();
	}

	klasa(double x)
	{
		this->init();
		this->zmienna = x;
	}
};

Dzięki za info :)
Ogólnie to chodzi mi o to, że chciałbym, żeby kilka funkcji nie mogło być wywołanych przed wywołaniem innych funkcji. Dlatego chciałbym przykładowo zadeklarować kilka zmiennych typu bool i przypisać im na wstępie wartość 0 (np. bool zmienna = 0; -> następnie w funkcjach, które mają być wywołane wcześniej na końcu wpisuję zmienna = 1; -> a w funkcjach, które mają być wywołane później w pisuję if(zmienna){/.../}.
Chodzi o takie zabezpieczenie, żeby jedna czy więcej funkcji nie narobiła mi kłopotów w klasie :D
Natomiast nie chcę używać do tego konstruktorów bo nie chcę, żeby użytkownik musiał pamiętać o wywołaniu jakiegoś konstruktora tylko, żeby się jakoś zabezpieczyć...

Obecnie poradziłem sobie z tym problemem w ten sposób, że utworzyłem sobie klasę pomocniczą typu:

class control {
bool check1;
bool check2;
bool check3;
control(){check = 0;}
bool check(){
if(check1 && check2 && check3)
return 1;
else
return 0;
}
};

i w głównej klasie robię sobie taki obiekt -> następnie w każdej ważnej funkcji robię np. tak: obiekt.check1 = 1; -> a w funkcji, która ma być wykonana po wywołaniu innych funkcji tak: if(obiekt.check()){
//...
}

Póki co działa! :D

0

ups, mały błąd -> powinno być w konstruktorze tak:

control(){check1 = 0, check2=0, check3=0;} 
0

Trochę utrudniasz sobie życie, przecież jakiś konstruktor zawsze się wywoła, więc nie trzeba o tym pamiętać. No, ale tak też można.

0
byku_guzio napisał(a)

Trochę utrudniasz sobie życie, przecież jakiś konstruktor zawsze się wywoła, więc nie trzeba o tym pamiętać. No, ale tak też można.

Tak, masz rację, ale chodziło również o to, żeby nie wpisywać w każdym konstruktorze przypisania zmiennej 0 :)

0

Nie da się zapomnieć wywołać konstruktora. Zawsze musi być jakiś wywołany. Twoim zadaniem jest sprawić, aby każdy z konstruktorów w pełni wszystko zainicjował. Niech każdy z konstruktorów na początku ustawia wszystkie "check" na false i tyle. Wygląda to tak jakbyś na siłę chciał sobie utrudnić życie.

0
adf88 napisał(a)

Nie da się zapomnieć wywołać konstruktora. Zawsze musi być jakiś wywołany. Twoim zadaniem jest sprawić, aby każdy z konstruktorów w pełni wszystko zainicjował. Niech każdy z konstruktorów na początku ustawia wszystkie "check" na false i tyle. Wygląda to tak jakbyś na siłę chciał sobie utrudnić życie.

Ale ja nie twierdzę, że się da zapomnieć. Chodzi o to, żeby nie wpychać do każdego konstruktora takiej inicjalizacji - bo jak wywołam wszystkie konieczne funkcje do wywołania pewnej szczególnej funkcji a następnie skorzystam znowu z konstruktora to on mi znowu ustawi te zmienne na 0 i znowu będę musiał wykonać pewne funkcje, żeby wywołać tą szczególną... - takie trochę poplątane ale...

0

To teraz mi powiedz w jaki sposób ponownie wywołać konstruktor o_O

0
byku_guzio napisał(a)

To teraz mi powiedz w jaki sposób ponownie wywołać konstruktor o_O

A nie można tak:

klasa obiekt(x,y); //pierwsze wywołanie konstruktora
obiekt(z,r); // drugie wywołanie
obiekt(a,b); // trzecie itd.
obiekt(a,b,c,d); //wywołanie innego konstruktora
0

Nie, nie można tak.

0
byku_guzio napisał(a)

Nie, nie można tak.

Uuu, to muszę zweryfikować swoją wiedzę z zakresu konstruktorów ;). Myślałem, że to jest normalna funkcja, którą można używać do woli...
Przecież podobnie jest w klasie string - można stworzyć obiekt typu:

string text = "pierwsze wywołanie"; 
text = "drugie wywołanie"; (?)
0

Przy drugim wywołaniu tworzysz nowy obiekt, a stary jest niszczony.

0

Przy drugim wywołaniu odpala się operator przypisania.

0
adf88 napisał(a)

Przy drugim wywołaniu tworzysz nowy obiekt, a stary jest niszczony.

Nie kapuję. Czy mógłbyś rozwinąć myśl? :)
Myślałem, że "text" jest obiektem i tworzy się go z użyciem nazwy klasy -> czyli w tym wypadku "string".

0

Generalnie chodzi o to, że

string text = "pierwsze wywołanie"; 
text = "drugie wywołanie";

można by zapisać w ten sposób:

string text("pierwsze wywołanie"); 
string nowy_text("drugie wywołanie");
text = nowy_text; // tracimy stary obiekt

i wyjdzie na to samo.

No chyb że operator przypisania jest przeciążony.

0

Super! dzięki za wyjaśnienie ;)
Trochę się zdziwiłem niemożnością użycia powtórnego konstruktora... :( W takim razie rzeczywiście chyba najlepiej zrobić w konstruktorze przypisanie :)
Rozumiem również, że niemożność użycia powtórnego konstruktora odnosi się również do dwóch różnych konstruktorów? Czyli jak mamy przeładowanie konstruktora to i tak można użyć tylko jeden z nich?
pozdrawiam!

0

Tak, z tym wyjątkiem, że w nowym standardzie z jednego konstruktora można wywołać inny.

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