Wywołaniem statycznej metody klasy

0

Witam,

Mam problem z wywołaniem statycznej metody klasy,
deklaracja klasy:

class Figura{
protected:
	char *nazwa;
	float pow;
	static int liczba_ob;
	friend ostream & operator<<(ostream &wyjscie, const Figura& f);
public:
	static void ile_ob(){ cout<<"Liczba obiektow: " <<liczba_ob <<endl; };
	Figura();
	Figura(Figura &f);
	~Figura();

};
int Figura::liczba_ob=0; 

A wywołuje ją tak:

 Figura::ile_ob();   //TUTAJ BLAD

Program sie uruchamia po czym wyskakuje okienko Debug Library:
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

Ktoś wie o co chodzi?

0

Błąd jest ale nie w podanym fragmencie kodu.

0
#include <iostream>
#include <ctime>
using namespace std;
//DEFINICJE KLAS//

//KLASA FIGURA//

class Figura{
protected:
	char *nazwa;
	float pow;
	static int liczba_ob;
	friend ostream & operator<<(ostream &wyjscie, const Figura& f);
public:
	static void ile_ob(){ cout<<"Liczba obiektow: " <<liczba_ob <<endl; };
	Figura();
	Figura(Figura &f);
	~Figura();

};
int Figura::liczba_ob=0;


//KLASA KOLO//

class Kolo: public Figura{
private:
	float promien;
	friend ostream & operator<<(ostream &wyjscie, const Kolo& k);
public:
	Kolo();
	Kolo(Kolo &k);
	~Kolo();
};

//KLASA KWADRAT//

class Kwadrat: public Figura{
protected:
	float bok;
	friend ostream & operator<<(ostream &wyjscie, const Kwadrat& k);
public:
	Kwadrat();
	Kwadrat(Kwadrat &k);
	~Kwadrat();
};

//KLASA PROSTOKAT//

class Prostokat: public Kwadrat{
private:
	float wysokosc;
	friend ostream & operator<<(ostream &wyjscie, const Prostokat& p);
public:
	Prostokat();
	Prostokat(Prostokat &p);
	~Prostokat();
};

//****************MAIN*******************MAIN**********************MAIN***********************MAIN*******************MAIN******************//
void main(){
	srand(time(NULL));
	Figura *wsktab[10];
	int tmp;
	Figura::ile_ob();  
	cout <<"Generowanie obiektow: "<<endl;
	for(int i=0; i<10; i++){
		tmp = (rand()%3)+1;
		switch (tmp){
			case 1:	{
					Figura *f = new Figura();
					cout <<*f;
					wsktab[i] = f;
					break;
					}
			case 2: {
					Kolo *k = new Kolo();
					cout <<*k;
					wsktab[i] = k;
					break;
					}
			case 3: {
					Kwadrat *kw = new Kwadrat();
					cout <<*kw;
					wsktab[i] = kw;
					break;
					}

		}

	}
	Figura::ile_ob(); 
	cout <<"Wypisywanie z tablicy: " <<endl;
	for(int i=0; i<10; i++){
		cout << *wsktab[i];
	}
	for(int i=0;i<10;i++)
		delete [] wsktab[i];

	cout <<"Pozwolnieuniu pamieci:"<<endl;
	Figura::ile_ob();
	getchar();


}
//***************************************************************************************************************************************
//DEFINICJE METOD Z KALS//
//*****KLASA FIGURA******//
ostream & operator<<(ostream &wyjscie, const Figura& f){
	return wyjscie <<"Nazwa figury: " <<f.nazwa <<endl <<"Powierzchnia figury: " <<f.pow <<endl <<endl;
}
Figura::Figura(){
	nazwa = "Figura";
	pow = 0;
	liczba_ob++;
}
Figura::Figura(Figura &f){
	liczba_ob++;
	nazwa = f.nazwa;
	pow = f.pow;
}
Figura::~Figura(){
	liczba_ob--;
}

//*****KLASA KOLO*****//
ostream & operator<<(ostream &wyjscie, const Kolo& k){
	return wyjscie <<"Nazwa figury: " <<k.nazwa <<endl <<"Powierzchnia figury: " <<k.pow <<endl <<"Promiec kola: " <<k.promien <<endl;
}
Kolo::Kolo(){
	nazwa = "Kolo";
	pow = 0;
	promien = 0;
	liczba_ob++;
}
Kolo::Kolo(Kolo &k){
	liczba_ob++;
	nazwa = k.nazwa;
	pow = k.pow;
	promien = k.promien;
}
Kolo::~Kolo(){
	liczba_ob--;
}

//*****KLASA KWADRAT*****//
ostream & operator<<(ostream &wyjscie, const Kwadrat& k){
	return wyjscie <<"Nazwa figury: " <<k.nazwa <<endl <<"Powierzchnia figury: " <<k.pow <<endl <<"Bok Kwadratu: " <<k.bok <<endl;
}
Kwadrat::Kwadrat(){
	nazwa = "Kwadrat";
	pow = 0;
	bok = 0;
	liczba_ob++;
}
Kwadrat::Kwadrat(Kwadrat &k){
	liczba_ob++;
	nazwa = k.nazwa;
	pow = k.pow;
	bok = k.bok;
}
Kwadrat::~Kwadrat(){
	liczba_ob--;
}

//*****KLASA PROSTOKAT*****//
ostream & operator<<(ostream &wyjscie, const Prostokat& p){
	return wyjscie <<"Nazwa figury: " <<p.nazwa <<endl <<"Powierzchnia figury: " <<p.pow <<endl <<"Bok prostokatu: " <<p.bok <<"Wysokosc prostokatu: "<<p.wysokosc<< endl;
}
Prostokat::Prostokat(){
	nazwa = "Prostokat";
	pow = 0;
	bok = 0;
	wysokosc = 0;
	liczba_ob++;
}
Prostokat::Prostokat(Prostokat &p){
	liczba_ob++;
	nazwa = p.nazwa;
	pow = p.pow;
	bok = p.bok;
	wysokosc = p.wysokosc;
}
Prostokat::~Prostokat(){
	liczba_ob--;
} 

OK. Blad w pętli przy zwalnianiu pamięci z tablicy.

0

Ten błąd oznacza, że nieprawidłowo zarządzasz pamięcią, najprawdopodobniej zwalniasz jakiś obiekt dwa razy!

Po przejrzeniu kodu widzę, że problemem jest to iż używasz operatora delete [] zamiast zwykłego delete.
Maz zwalniać pojedyncze obiekty, a nie ich tablicę!

1
  1. Destruktor klasy Figura musi być wirtualny.
  2. Konstruktory klas pochodnych muszą wywoływać konstruktor klasy Figura
  3. liczba_ob powinna być zmieniana tylko w konstruktorze i destruktorze klasy Figura.
0
_13th_Dragon napisał(a):

Destruktor klasy Figura musi być wirtualny.

  1. Konstruktory klas pochodnych muszą wywoływać konstruktor klasy Figura
  2. liczba_ob powinna być zmieniana tylko w konstruktorze i destruktorze klasy Figura.

1 i 3 ok rozumiem poprawiłem, ale pkt 2 nie rozumiem. Jak tworze obiekt klasy np. kwadrat to jest odpalany konstruktor figury, a potem kwadratu to po co jeszcze w konstruktorze kwadratu wywoływać konstruktor figury? Wyjaśnij mi to bo dopiero zaczynam programować i może czegoś jeszcze nie wiem, z góry dziękuję :)

1
Kolo::Kolo():Figura() {
    nazwa = "Kolo";
    promien = 0;
}
0

Samą implementację rozumiem, ale dlaczego tak trzeba zrobić?
Dopisałem do konstruktora od każdej klasy

cout <<"Kostruktor %NAZWAKLASY%<<endl; 

. I przy losowaniu jeśli switch wszedł w opcję zrobienia np. obiektu klasy Kwadrat to lista wywołanych konstruktorów jest następująca:
Konstruktor Figury
Konstruktor Kwadratu
Nazwa: Kwadrat itd...

Czyli ten konstruktor figury przy tworzeniu klasy pochodnej jest wywołany z automatu, dlaczego mam go wywoływać jeszcze osobno w każdym konstruktorze innej klasy?

1

Konstruktor klasy bazowej sam się wywoła o ile bazowa ma konstruktor domyślny, więc w przypadku konstruktora Kolo() to warto zrobić jedynie dla porządku, co innego w przypadku (aby wiedzieć czemu nie trzeba zwiększać licba_ob) zaś w przypadku Kolo::Kolo(Kolo &k) nie jest to tylko dla porządku.

0

Ok rozumiem, dziękuję bardzo :)

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