Zmienna statyczna w klasie licząca ile klas powstało

0

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.

1

Niestety nie wiem tylko gdzie umieścić linijkę kodu z inkrementacją tej zmiennej.

W konstruktorach.

0

@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?

1

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();
}
0

@several: Dziękuję bardzo wszystko ładnie działa :)
EDIT: A jak zrobić coś takiego z polem const?

2

Nie da się, modyfikacja const obiektu to UB.

0
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ć.

0

Jak masz klasę const (a nie zmienną statyczną - ta nie może być const, gdy chcesz ją inkrementować), to zadeklaruj tę zmienną jako mutable.

1

Klasa nie może być const, a kwalifikator obiektu klasy nie ma wpływu na zmienne statyczne.

0

Chodziło mi o obiekt klasy. Ot zwykłe przejęzyczenie.

1

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.

0

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ć?

0
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 :)

3
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;
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? :)

4

jaki cout napisać w mainie żeby zobaczyć jak to działa?

Nie przeginaj.

0

@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.

0

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.

0

@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.

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