Wywołanie funkcji w klasie , używając wskaźnika

0

Stworzyłem klasę Cint przechowującą dwa inty (a,b)
I klase Ctab która składa się z obiektów Cint.
Mój kod wygląda tak

 #include <iostream>
using namespace std;

class Cint{
public:
	int a,b;
	Cint(char _a,int _b):a(_a),b(_b){}
	Cint():a(0),b(0){}
	void wypisz(){cout<<"A "<<a<<" B "<<b<<"\n";}

};
class Ctab{
public:
	Cint *tab;
	int numbers_of_objects;
	Ctab():numbers_of_objects(0){}
	void wypiszo(){
		for(int i=0;i<numbers_of_objects;i++){
			tab->wypisz();

		}
	}
	void dodaj(Cint o){
		
		Cint *buff=new Cint[numbers_of_objects];
		for(int i=0; i<numbers_of_objects; i++){
			buff[i]=tab[i];
		}
		tab = new Cint[numbers_of_objects+1];
		for(int i=0; i<numbers_of_objects; i++)
			tab[i]=buff[i];
		tab[numbers_of_objects]=o;
		delete []buff;
		numbers_of_objects++;
	}
};
int main(){
	Cint a(1,2),b(10,20);
	Ctab object;
	object.dodaj(a);
	object.dodaj(b);
	object.wypiszo();
		return 0;
}

Jak wypisać zmienne a,b wszystkich obiektów znajdujących się w klasie Ctab?

void wypiszo(){
		for(int i=0;i<numbers_of_objects;i++){
			tab->wypisz();

		}
	} 

próbowałem dodać do tab=tab+2*4 (klasa cint to dwa inty), lecz to nie pomaga,
Niestety nie mogę używać vector,list itd, tylko muszę dynamiczne przydzielać pamięć

1

tab[i].wypisz();

I przemyśl dokładnie metodę Ctab::dodaj():

  1. przy pierwszym dodaniu alokujesz w niej zerowy obszar pamięci, bo numbers_of_objects = 0
  2. niepotrzebnie tworzysz 2 bufory i kopiujesz między nimi dane, wystarczy jeden buff o większym rozmiarze, do niego przekopiowujesz istniejące dane, dodajesz nowy element i robisz delete[] tab i tab = buff
  3. nie zwiększaj buforu o jeden - beznadzejna wydajność przy dodawaniu kolejnych elementów. Zamiast tego zwiększaj go proporcjonalnie, np. x1.5 lub x2. Dodaj, podobnie jak w std::vector, dodatkową zmienną, która będzie mowiła o wielkości bufora, a druga ile rzeczywiście jest w nim zapisanych obiektów (odpowiedniki vector::size() i vector::capacity()). Alokujesz nową pamięć tylko wtedy, gdy cały bufor jest już wypełniony.
0

hmm dzięki, dał bym sobie rękę uciąć, że tak sprawdzałem i nie działało ;)
Poprawiłem kod, można użyć operatora dodawania

 Ctab & operator+=(const Cint &o){ 
		if(numbers_of_objects==0){
			tab = new Cint[numbers_of_objects+1];
		}else{	
			Cint *buff=new Cint[numbers_of_objects];
			for(int i=0; i<numbers_of_objects; i++){
				buff[i]=tab[i];
			}
			tab = new Cint[numbers_of_objects+1];
			for(int i=0; i<numbers_of_objects; i++){
				tab[i]=buff[i];
			}
			delete []buff;
		}
		tab[numbers_of_objects]=o;
		numbers_of_objects++;
		return *this;
	}

Jednak nie rozumiem twojej uwagi nr 2,
3 uwaga słuszna jednak chcę żeby to było jak najprościej a nie jak najoptymalniej

///chcialbym porownac czy klasa Ctab zawiera dany Cint
napisałem funkcjie

bool contain( Cint &o){
		for(int i=0;i<numbers_of_objects;i++){
			if(o.a==tab[i].a && o.b==tab[i].b)
				return 1;
			}
		}
		return 0;
	} 

Działa, jednak domyślam się że nie jest to poprawny sposób, jak inaczej można to napisać?

1

Odnośnie uwagi nr 2: chodzi o to, że w tab masz tablicę Cintów. Obecnie robisz tak, że tworzysz buff, kopiujesz do niego dane z tab, potem alokujesz nowy tab, kopiujesz do niego dane z buff i na końcu dodajesz nowy obiekt cInt. Chodzi mi o to, że można prościej - tworzysz nowy buff o jeden większy od rozmiaru tab, kopiujesz do niego dane z tab i na końcu dodajesz nowy Cint. Potem usuwasz tab i przypisujesz mu adres buff:

int* buff = new int[numbers_of_objects+1];
for(int i=0; i<numbers_of_objects; i++)
buff[i] = tab[i];

buff[numbers_of_objects] = o;
delete[] tab;
tab = buff;

Masz jedną alokację pamięci zamiast dwóch. A dodatkowo u siebie masz jeszcze wyciek pamięci, bo nie usuwasz starego tab, tylko od razu alokujesz dla niego nową pamięć.

Odnośnie contain (powinno być raczej contains ;) ) - może być tak jak jest teraz, ale z małą poprawką: ta metoda zwraca bool, a ty w kodzie piszesz "return 1" i "return 0", a powinno być "return true/false". Możesz też ją zmienić tak, że klasa Cint będzie implementować operator== i wtedy możesz metodę contain(s) zapisać:

bool contain( Cint &o)
{
for(int i=0;i<numbers_of_objects;i++)
{
if(o==tab[i])
{
return true;
}
}
return false;
}

albo zrobić to z użyciem std::find():
http://www.cplusplus.com/reference/algorithm/find

0

int* buff = new int[numbers_of_objects+1];
for(int i=0; i<numbers_of_objects; i++)
buff[i] = tab[i];

buff[numbers_of_objects] = o;
delete[] tab;
tab = buff;

Program się kompiluje, i potem wysypuje:P Błąd: BLOCK_ TYPE_IS VALID (pHead->nBlockuse) jesli nie skasuje tab to wszystko działa

//zawsze myslalem ze 1 = true a 0=false i nie ma roznicy jak to zapisze

1

A nie jest tak, że wysypuje się przy pierwszym dodaniu elementu, gdy tab jest wiszącym wskaźnikiem? Bo widzę, że nie ustawiasz go na NULL/nullptr/0 w konstruktorze i wtedy przy pierwszym wstawieniu chcesz zwolnić jakiś losowy obszar pamięci.

0

Rzeczywiście, złe nawyki z PHP, zapominam o tym że trzeba ustawiać na 0:P

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