[c++] szablon vector. Przekazanie vectora do skladnika klasy

0

Czesc.
Mam na zaliczenie projekt i utknalem w martwym punkcie. Mialem do stworzenia klase do obslugi macierzy. Stworzylem wszytko uzywajac dynamicznych tablic wielowymiarowych. Teraz niestety musze to zrobic za pomaca szablonu vector.

Mam cos takiego:

macierz::macierz(unsigned int wie,unsigned int kol)
{
int i;
int j;
    if(wie!= 0 && kol!= 0)
    {
    vector< vector<int> > tablica(wie, vector<int>(kol,0));


 int ii, jj;
 for(ii=0; ii < wie; ii++)
 {
 for(jj=0; jj < kol; jj++)
 {
        tablica[ii][jj]=rand()%26;
        cout << tablica[ii][jj]<< " ";

 }
 cout << endl;
 }

 cout << endl;
}

Moja klasa wyglada nastepujaco:

class macierz{

    int wiersz;
    int kolumna;
    //int **tab 

public:

    macierz(unsigned int wie,unsigned int kol);
};

Wszytko niby ladnie sie wyswietla ale nie wiem jak przekazac ten uzupelniony vector do skladnika klasy.Wczesniej robile to za pomoca **tab a sama tablce tworzylem dynamicznie. Jak to rozgryźć na tych vctorach ?

0

„Normalnie”, przez wartość (standardowe pojemniki mają operatory przypisania i wszystko inne i zadbają o właściwą alokację zasobów):

std::vector< std::vector< int > > tabl; // deklaracja składowej wewnątrz klasy


tabl = tablica; // na końcu konstruktora.

Nie jest to jednak wydajne, lepiej byłoby chyba, gdyby konstruktor od razu wpisywał dane do składowej klasy (odejdzie kopiowanie):


// Składowa std::vector< std::vector< int > > tabl; wewnątrz klasy jak wyżej

macierz::macierz(unsigned int wie,unsigned int kol)
{
int i;
int j;
    if(wie!= 0 && kol!= 0)
    {
       for (int i = 0; i < wie; ++i)
       {
            std::vector<int> tmp;
            for (int j = 0; j < kol; ++j)
            {
                  tmp.push_back(rand()%26);
                  std::cout << tmp.back() << " ";
            };
 
            tabl.push_back(tmp);
            std::cout << "\n";
      };

}

push_back jest metodą wektora która dokłada element na końcu
back natomiast jest metodą, która daje referencję do ostatniego elementu wektora

0

Drobna modyfikacja...

macierz::macierz(unsigned int wie,unsigned int kol)
{
	int i;
	int j;
		
	if(wie== 0 || kol== 0)return;

	std::vector<int> tmp;
	
	tabl.resize(wie);
	
	for (int i = 0; i < wie; ++i)
	{
		tmp.reserve(kol);
		
		for (int j = 0; j < kol; ++j)
		{
			tmp.push_back(rand()%26);
			std::cout << tmp.back() << " ";
		}

		tabl[i].swap(tmp);
		std::cout << "\n";
	}
}
0

A czy w tej chwili potrzebny jest destruktor ?

No i mam jeszcze pytanie czy konieczny jest operato przypisania i konstruktor kopijuacy ? Jesli zrobilem to na razie tym pierszym sposobem to chyba sa potrzebne ?

No i jeszcze kilka pytan odnosnie tego kodu:

macierz::macierz(unsigned int wie,unsigned int kol)
{
        int i;
        int j;
               
        if(wie== 0 || kol== 0)return;

        std::vector<int> tmp;  // Tu tworzymy wektor
       
        tabl.resize(wie);  // Tu zmieniemy rozmiar na odpowiednia liczbe wierszy. Tzn ze wektor jest jeby pionowy ?
       
        for (int i = 0; i < wie; ++i)
        {
                tmp.reserve(kol); // dla kazdej komorki wektora pierszego rezerwujemy wektor poziomy o rozmairze kol?
               
                for (int j = 0; j < kol; ++j)
                {
                        tmp.push_back(rand()%26); // I tu mam pytanie czemu to wszytko jest w petli skoro nigdzie nie uzywamy np tmp[i]? Szablon wektor sam wie ze jak jest w petli to przechdzi po kolejnych elemenatch ?
                        std::cout << tmp.back() << " ";
                }

                tabl[i].swap(tmp); // Tu kopiujemy do tabl[i] elementy tmp
                std::cout << "\n";
        }
}

Prosze napiszcie mi czy dobrze rozumieje, bo nie chce tego uzyc poki tego do konca nie zrozumiem. W ostatecznosci uzyskalismy wektor o rozmaierze i ktorej kazdy element jest wektorem o rozmiarze j ?

0

A czy w tej chwili potrzebny jest destruktor ?

Jeśli nie ma pamięci do zwolnienia to nie.

No i mam jeszcze pytanie czy konieczny jest operato przypisania i konstruktor kopijuacy ?

Jeśli korzystasz z vectorów - nie.

Tzn ze wektor jest jeby pionowy ?

Tak.

// I tu mam pytanie czemu to wszytko jest w petli skoro nigdzie nie uzywamy np tmp[i]? Szablon wektor sam wie ze jak jest w petli to przechdzi po kolejnych elemenatch ?

reserve to nie to samo co resize. Ta pętla dodaje elementy do vectora (push_back), a to reserve to tylko drobna optymalizacja - jedna alokacja zamiast kilku.

// Tu kopiujemy do tabl[i] elementy tmp

Nie kopiujemy, tylko podmieniamy zawartość - drobna optymalizacja.

Prosze napiszcie mi czy dobrze rozumieje

"rozumieje"? :|

W ostatecznosci uzyskalismy wektor o rozmaierze [...]

Tak.

0

okej czyli wszytko jasne :) a mialo byc rozumuje :) moj blad, ale juz mi sie mieszaja literki :).

0

1' jesli w klasie masz int** to potrzebny destruktor ktory to zwolni. jesli zas masz vector<vector<int>> to nic nie potrzeba, on sie sam zniszczy poprawnie

2' domyslny cctor i op= sa poprawne sa bezpieczne i poprawne

3'

  • tu tworzymy wektor tymczasowy udajacy wypelniana kolumne
  • tab1 to pole Twojego obiektu macierz, i jest to wektor trzymajacy wektory intow. inty sa komorkami. wektory intow sa wierszami. wektor wektorow intow jest macierza. tak wiec 'tab1' jest zbiorem wierszy. stad resizeujemy go tak, aby wszystkie wiersze sie w niego zmiescily
  • dla kazdego WIERSZA, reservujemy my tyle miejsca, aby w niego weszlo KOL komorek [tyle komorek co ma byc kolumn]. reserve NIE OZNACZA resize. dlugosc tego wiersza nadal wynosi ZERO, ale ma on zarezerwowane troche pamieci, zeby potem wstawianie komorek bylo szybsze
  • tutaj jest w linijce uzyty PUSH_BACK. ta metoda powoduje powiekszenie wektora o oczko i dostawienie podanego elementu na koniec wektora. innymi slowy do wiersza DOSTAWIAMY komorke o podanej wartosci. dostawienie jest szybkie, bo wczesniej wektor mial juz miejsce zarezerwowane z gory na wszystkie komorki
  • nie kopiujemy, tylko zamieniamy. dokladniej - zamieniamy PUSTY tab[i] na WYPELNIONY tmp. zamiana jest szybsza niz kopia/podstawienie bo wektory wymieniaja sie wskaznikami na zawartosc etc

wsio juz jasne?:)

//edit: hihi.. cos tak czulem ze jak odejde od kompa zanim nacisnalem 'wyslij' to ktos mnie wyprzedzi:))

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