latajacaryba Temat założony przez niniejszego użytkownika |
Przesyłanie do funkcji przez referencje wektora wskaźników » 2017-05-15 15:31:00 Witam. Slyszalem, ze ze wzgledu na jakies tam (nie wiem jakie) rzeczy warto zamiast wektora obiektow miec wektor wskaznikow na te obiekty. Jak go przekazac do funkcji przez referencje?
|
|
michal11 |
» 2017-05-15 16:14:41 void fun( const std::vector < Type *>& vec ); oczywiście zamiast zwykłego wskaźnika polecam smart pointery, tutaj to tylko przykład. |
|
DejaVu |
» 2017-05-15 17:24:37 Jeżeli nie zarezerwujesz pamięci w vectorze to powiększanie vectora będzie powodowało realokacje tablicy, w tym wykonywanie głębokiej kopii obiektów, które przechowujesz w vectorze. W przypadku przechowywania wskaźników na obiekty wykonujesz kopię tylko de-facto wskaźników. |
|
Monika90 |
» 2017-05-15 18:06:52 Nie ma powodu żeby zmiany rozmiaru wektora powodowały głębokie kopiowanie, wystarczy zaimplementować operacje przenoszenia (w klasie przechowywanych obiektów). |
|
latajacaryba Temat założony przez niniejszego użytkownika |
» 2017-05-15 18:51:11 Jeżeli nie zarezerwujesz pamięci w vectorze |
Używam ich po to, żeby nie musieć rezerwować pamięci, w innym przypadku użyłbym zwykłej tablicy wskaźników :) powiększanie vectora będzie powodowało realokacje tablicy, w tym wykonywanie głębokiej kopii obiektów |
Co masz na myśli? Czym jest ta głęboka kopia obiektów? Nie ma powodu żeby zmiany rozmiaru wektora powodowały głębokie kopiowanie, wystarczy zaimplementować operacje przenoszenia (w klasie przechowywanych obiektów). |
Co to jest ta operacja przenoszenia? Generalnie plan jest taki: Mam wektor wskaźników, czasem są już tam wskaźniki na dynamicznie zaalokowane obiekty, czasem nie. Przesyłam go do funkcji. Jeśli zawiera jakieś wskaźniki, czytaj wektor.size() > 0 to: delete wektor[ i ]; wektor[ i ].pop_back;
Następnie tworze nowe "komórki" wektora, to jest: wektor.push_back( new Typ(...) )
Także właśnie tak to wygląda i dlatego potrzebuje przesyłać akurat wskaźnik wektorów. Może to jakoś przybliżyło problem. |
|
jankowalski25 |
» 2017-05-15 19:10:36 std::vector to taki twór udający tablicę o dynamicznym rozmiarze. W praktyce zawsze przy przydzielaniu pamięci trzeba podać, ile jej chcemy. Sprowadza się to do tego, że najpierw jest przydzielana tablica o jakimś rozmiarze, a jak się zapełni, to następuje: 1. Przydzielenie pamięci na nową, większą tablicę. 2. Skopiowanie (lub przeniesienie) wszystkiego ze starej tablicy do nowej. 3. Zwolnienie starej tablicy. Czym jest ta głęboka kopia obiektów? |
Po prostu każdy obiekt trzeba będzie skopiować lub przenieść ze starej tablicy do nowej. Sam użytkownik tego nie widzi, ale wewnątrz wektora takie działania mają miejsce. Jak to zobaczyć? 1. Tworzysz własną klasę, która informuje o wywołaniu swoich konstruktorów, destruktorów, ma przeciążone odpowiednie operatory, i tak dalej. 2. Tworzysz wektor używający obiektów tej klasy. 3. Używasz metody reserve. 4. Wkładasz więcej elementów, niż rezerwujesz i patrzysz, co się dzieje. 5. Jeśli kompilator będzie sprytny, możesz to uzależnić od danych podawanych przez użytkownika. Inaczej optymalizacje mogą spowodować, że kompilator sam sobie wstawi odpowiedni rozmiar, jeśli napiszesz wypełnianie wektora "na sztywno". Co to jest ta operacja przenoszenia? |
Poczytaj o konstruktorze przeniesienia (ang. move constructor), nie mylić z konstruktorem kopiującym. |
|
karambaHZP |
» 2017-05-15 19:38:24 |
|
latajacaryba Temat założony przez niniejszego użytkownika |
» 2017-05-18 00:44:45 @Michal11 Probowalem tak, jak pisales, przy czym coś popsułem przy wywolywaniu funkcji, jakieś nowe dla mnie logi sie pojawiaja :/ jutro sprawdze dokladnie, ale to chyba wina innego argumentu. W każdym razie na pewno Twoja pomoc nie pójdzie na marne ;) Ok, rozumiem działanie wektora (Wielkie dzięki za przystępne wyjaśnienie dla Jana Kowalskiego), zaniepokoiło mnie natomiast to, co pisał DejaVu: Jeżeli nie zarezerwujesz pamięci w vectorze to powiększanie vectora będzie powodowało realokacje tablicy, w tym wykonywanie głębokiej kopii obiektów, które przechowujesz w vectorze. W przypadku przechowywania wskaźników na obiekty wykonujesz kopię tylko de-facto wskaźników. |
Czy to znaczy, że te nowe wskaźniki nie będą już wskazywały na te obszary pamięci, na które wskazywały ich poprzedniki? I czy właściwie opłaca mi się ten wektor wskaźników, nie lepszy będzie wektor obiektów? Bo elementów nie będzie zbyt dużo, myślę, że z 30-40 w skrajnych przypadkach z 70 i wiem, że podobno wektor wskaźników jest z jakichś tam powodów lepszy/szybszy to nie wiem, czy to gra warta świeczki. I jeszcze jedno na marginesie; Wektor to (w dużym uproszczeniu) dynamiczna tablica wskaźników? Kiedy mamy std::vector < int > wekt; i wywołamy wekt.push_back( 5 ); to będzie to coś takiego jak: wekt[ n ] = new int( 5 ) ? Bo jak niby inaczej byłaby zwalniana pamięć w trakcie działania programu... Czy się mylę? |
|
« 1 » 2 3 |