Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przesyłanie do funkcji przez referencje wektora wskaźników

Ostatnio zmodyfikowano 2017-05-19 16:55
Autor Wiadomość
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?
P-161151
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.
P-161152
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.
P-161153
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).
P-161154
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:
C/C++
delete wektor[ i ]; // usuwam obiekt na ktory wskazuje wskaznik (przypominam, dynamicznie zaalokowany)
wektor[ i ].pop_back;
Następnie tworze nowe "komórki" wektora, to jest:
C/C++
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.
P-161162
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 » standard C++ » vectorreserve.
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.
P-161163
karambaHZP
» 2017-05-15 19:38:24
P-161164
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ę?
P-161240
« 1 » 2 3
  Strona 1 z 3 Następna strona