Witam, chciałbym zaimplementować zmienna statyczna, która jest w klasie i liczy ile obiektów danej klasy stworzyłem w int main. Niestety nie wiem tylko gdzie umieścić linijkę kodu z inkrementacją tej zmiennej.
Niestety nie wiem tylko gdzie umieścić linijkę kodu z inkrementacją tej zmiennej.
W konstruktorach.
@several Najgorzej, że ta zmienna musi być prywatna, a jak umieszczam w konstruktorze to wywala mi błąd o tej właśnie prywatności. Da się to obejść czy to źle skonstruowane zadanie jest?
Powodem błędu na pewno nie jest prywatny specyfikator dostępu. Poniższy kod powinien działać we wszystkich znanych mi standardach:
#include <iostream>
class Type
{
static int var;
public:
Type(){var++;}
static int instances(){return var;}
};
int Type::var = 0;
int main() {
Type t1, t2, t3;
std::cout << Type::instances();
}
@several: Dziękuję bardzo wszystko ładnie działa :)
EDIT: A jak zrobić coś takiego z polem const?
Nie da się, modyfikacja const obiektu to UB.
Kardam napisał(a):
Witam, chciałbym zaimplementować zmienna statyczna, która jest w klasie i liczy ile obiektów danej klasy stworzyłem w int main.
Ja tutaj tylko nadmienię, że o ile pomysł Brata Severala jest ogólnie słuszny, to wiedz, że taki statyczny licznik będzie zliczał każde utworzenie obiektu, nie tylko w main(). Póki nigdzie poza main() ich nie tworzysz to spoko, nie ma problemu przekłamań wskazań przez licznik. Jeśli jednak ma zliczać tylko i wyłącznie utworzenia obiektu w main, to rzecz nieco się komplikuje,i trzeba sobie poradzić przez użycie makra FUNCTION:
#include <iostream>
#include <string>
class Type
{
public:
Type(const std::string &invokePlace = "")
{
if (invokePlace == "main")
{
counter++;
}
}
static int objectsCreatedInMain()
{
return counter;
}
private:
static int counter;
};
int Type::counter = 0;
void notMain()
{
Type t(__FUNCTION__);
}
int main()
{
notMain();
Type t1(__FUNCTION__), t2(__FUNCTION__), t3(__FUNCTION__);
std::cout << Type::objectsCreatedInMain();
}
https://onlinegdb.com/SJJwfKG07
wadą jest, iż z obsługą FUNCTION przez kompilatory bywa różnie, ale w tych nowszych to wg tego co znalazłem powinno działać.
Jak masz klasę const (a nie zmienną statyczną - ta nie może być const, gdy chcesz ją inkrementować), to zadeklaruj tę zmienną jako mutable.
Klasa nie może być const, a kwalifikator obiektu klasy nie ma wpływu na zmienne statyczne.
Chodziło mi o obiekt klasy. Ot zwykłe przejęzyczenie.
tr, pieprzysz bzdury.
Zmienne/metody statyczne nie są wywoływane na rzecz jakiegoś konkretnego obiektu, ale całej klasy - zatem mają w głębokim poważaniu czy ktoś sobie zdefiniował jakieś instancje owej klasy jako const.
Dowód - starczy dopisać w moim kodzie const przed Type w main() i notMain(), a program nadal będzie działać zgodnie z oczekiwaniem.
Dziękuje za odpowiedzi. Z tym const chodzi mi o to, (a właściwie nie mi tylko to wymagania prowadzącego) że w klasie będzie zmienna powiedzmy const int nrComple. I ta zmienna ma przechowywać, informacje o tym, że ten obiekt został stworzony pierwszy, drugi itp. Coś w stylu indexowania tych klas. I tutaj rodzi się pytanie czy jest możliwe coś takiego zrobić?
MasterBLB napisał(a):
Kardam napisał(a):
Witam, chciałbym zaimplementować zmienna statyczna, która jest w klasie i liczy ile obiektów danej klasy stworzyłem w int main.
Ja tutaj tylko nadmienię, że o ile pomysł Brata Severala jest ogólnie słuszny, to wiedz, że taki statyczny licznik będzie zliczał każde utworzenie obiektu, nie tylko w main(). Póki nigdzie poza main() ich nie tworzysz to spoko, nie ma problemu przekłamań wskazań przez licznik. Jeśli jednak ma zliczać tylko i wyłącznie utworzenia obiektu w main, to rzecz nieco się komplikuje,i trzeba sobie poradzić przez użycie makra FUNCTION:
#include <iostream> #include <string> class Type { public: Type(const std::string &invokePlace = "") { if (invokePlace == "main") { counter++; } } static int objectsCreatedInMain() { return counter; } private: static int counter; }; int Type::counter = 0; void notMain() { Type t(__FUNCTION__); } int main() { notMain(); Type t1(__FUNCTION__), t2(__FUNCTION__), t3(__FUNCTION__); std::cout << Type::objectsCreatedInMain(); }
https://onlinegdb.com/SJJwfKG07
wadą jest, iż z obsługą FUNCTION przez kompilatory bywa różnie, ale w tych nowszych to wg tego co znalazłem powinno działać.
Prowadzący właśnie chciał, żeby każde stworzenie obiektu było liczone :)
Kardam napisał(a):
Dziękuje za odpowiedzi. Z tym const chodzi mi o to, (a właściwie nie mi tylko to wymagania prowadzącego) że w klasie będzie zmienna powiedzmy const int nrComple. I ta zmienna ma przechowywać, informacje o tym, że ten obiekt został stworzony pierwszy, drugi itp. Coś w stylu indexowania tych klas. I tutaj rodzi się pytanie czy jest możliwe coś takiego zrobić?
Da się, cały pic to dobrze zainicjalizować zmienną typu const:
class Type
{
public:
Type() : creationCount(++counter)//robi się to na liście inicjalizacyjnej
{}
int whichWasCreated() const
{
return creationCount;
}
private:
static int counter;
const int creationCount;
};
int Type::counter = 0;
@MasterBLB: Super, dziękuje powoli idzie to do przodu. Zaimplementowałem sobie i działa tylko teraz mam pytanie jaki cout napisać w mainie żeby zobaczyć jak to działa? :)
jaki cout napisać w mainie żeby zobaczyć jak to działa?
Nie przeginaj.
@several: Wiem, że to dla was banalne, ale ja jestem dość świeży w c++ i przepraszam za to. I wiem, że trzeba użyć funkcji whichWasCreated, ale on nie pobiera żadnych argumentów. I nie mam pojęcia jak to zrobić. Obiekt stworzyłem o nazwie c i dałem c.whichWasCreated i daje dziwny output.
Udzielające się w tym wątku osoby dobrze zdają sobie sprawę, że chcesz gotowca na zajęcia. Dostałeś już o wiele więcej niż powinieneś. W tym miejscu EOT z mojej strony.
@several: Nie ma problemu, akurat nie lubuje się w C++, a na przedmiot de facto "Programowanie obiektowe" musi być koniecznie C++. Linijek kodu mam około 60(wiem, że dla Was to tak na prawdę nic) samodzielnie napisanych także próbuję po prostu to jakoś pojąć. Dziękuję Ci i tak pięknie za poświęcony czas i wytłumaczenie w pierwszym poście co zrobić z tym static'em.