Witam. Mam problem, bowiem chciałbym stworzyć dynamiczną listę obiektów, do której mógłbym dodawać i z której mógłbym usuwać obiekty (które są wtedy niszczone i nie zaśmiecają pamięci). Używanie wskaźnika i słowa kluczowego "new" wydaje mi się nieco dziwne, ponieważ za każdym razem gdy chcę dodać nowy obiekt, muszę na nowo tworzyć dynamiczną tablicę, a usuwanie obiektów nie jest zbyt wygodne. Mógłby mi ktoś coś polecić? Podkreślam, że jestem początkujący w C++, lecz mam doświadczenie w UnrealScript (którego składnia jest bardzo podobna do C++). Z góry dziękuję za odpowiedzi.
Robisz sobie listę jedno lub dwu kierunkową, albo skorzystać z STL'a gdzie masz vectory ( jeśli potrzebujesz odwoływać się do poszczególnych elementów ( przeładowany operator [] ), wolne dodawanie i usuwanie elementów jeśli nie chodzi o 1 lub ostatni ) lub list ( jeśli będziesz głównie przeglądał je w pętlach ( dostęp do danych tylko iteratorem, ale za to stały czas dodawania i usuwania elementów w dowolnym miejscu ).
Dzięki za informację. Przeczytałem, że iteracja polega na ustawieniu pętli for, zadeklarowaniu iteratora i dodawania do niego 1, by przejść do następnego elementu, i mam pytanie. Czy można przeskoczyć od razu o 2 albo 3 elementy? Czy iterator ma coś wspólnego ze wskaźnikiem? Pozdrawiam.
Tak, iterator to taki jakby wskaźnik do pokazywania w kontenerach.
Ok, dzięki za pomoc.
Btw: Przesiadłem się z Dev-C++ na Visual C++ 2008 Express Edition, lecz aplikacja skompilowana w tym ostatnim wyłącza się z sugestią raportu błędu do Microsoftu, podczas gdy skompilowany pod Dev-C++ działa poprawnie. Czy może wiesz co może być tego powodem?
O ile dobrze pamiętam to strumienie inaczej działają w VC++ niż w gcc
Neo_b, pokaż kod, pokażą się sugestie. Sugestia raportu = paskudny crash. Wspominasz o pamięci, i właśnie pewnie tą pamięcią trochę źle operujesz. Przejrzyj wskaźniki, czy nie używasz po zwolnieniu, przejrzyj tablice, czy nie przekraczasz zakresu.
winerfresh: możesz rozwinąć, wszelkie niekompatybilności radośnie zbieram i sobie notuję - dla siebie, dla potomnych.
Np. stringi były źle obsługiwane przez cout, ale nie pamiętam za dobrze bo już dawno się rozstałem z VC++. To chyba było tak, że można było w obu użyć std:: string bez includowania <string>, ale w VC++( o ile dobrze pamiętam ) trzeba było pisać:
std::string s = "some text";
std::cout << s.c_string();
Ale naprawdę nie pamiętam.
a, to jeśli coś takiego, to sam się prosiłeś - działanie "nie dołączam, a działa", jest poleganiem na tym, że jakiś-nagłówek-gdzieś-jakoś używa wewnętrznie stringów. W pełni zależne od implementacji.
Zapewne dinkumware (autor stdliba c++ dla VC) zrobił dwa/trzy nagłówki wewnętrzne:
- deklaracja samej klasy string
- reszta klamotów (m.in. operatorów zaprzyjaźnionych)
- <string> właściwy, includujący jedynie 1+2
No i ktoś-gdzieś (np iostream) potrzebował (1), ale nie dołączał (2), bo potrzebny nie był, a zawsze to mniej kodu do kompilacji.
To taki sobie OT, w oczekiwaniu na kod od neo_b.
LRESULT CALLBACK nWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
int i;
vector offset;
HDC hdc;
switch(msg)
{
case WM_CLOSE:
if(MessageBox(hwnd, "Do you really want to quit?", "Quitting", 4|MB_ICONQUESTION)==IDYES)
{
PostQuitMessage(0);
return 0;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
if(!(wparam & MK_CONTROL))
{
CreateAtoms(vect(LOWORD(lparam), HIWORD(lparam), 0), 1, 0, 0);
break;
}
selected++;
if(selected>=AtomNumber)
{
selected=0;
}
break;
case WM_RBUTTONDOWN:
if(wparam & MK_SHIFT)
{
offset=vect(LOWORD(lparam), HIWORD(lparam), 0);
for(i=0; i<AtomNumber; i++)
{
Atoms[i].velocity=offset-Atoms[i].location;
}
break;
}else if(!(wparam & MK_CONTROL)){
offset=vect(LOWORD(lparam), HIWORD(lparam), 0)-Atoms[selected].location;
Atoms[selected].velocity=offset;
break;
}
Atoms[selected].velocity=vect(0,0,0);
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
}
Niestety więcej nie mogę pokazać. ;-P Program zawiesza się po 4 kliknięciu na okienko lewym klawiszem myszy.
Zmienna Atoms to pointer z dynamicznie przydzieloną tablicą. Mam zamiar użyć zamiast niego listy. A w ogóle to jaki kompilator polecacie? Dev-C++ nie ma wszystkich potrzebnych bibliotek, a VC++ ma jakieś inne biblioteki (na przykład wszystkie lub większość funkcji wymaga LPWSTR zamiast LPSTR).
Wybaczcie, zapomniałem dodać:
void CreateAtoms(vector Begin, int num, float distance, float error)
{
int OldAtomNum=0, i;
float randnum;
atom* NewAtoms;
if(AtomNumber>0)
{
NewAtoms=new atom[AtomNumber];
for(OldAtomNum=0; OldAtomNum<AtomNumber; OldAtomNum++)
{
NewAtoms[OldAtomNum]=Atoms[OldAtomNum];
}
delete[] Atoms;
}
AtomNumber+=num;
Atoms=new atom[AtomNumber];
srand(clock()+time(0));
for(i=0; i<AtomNumber; i++)
{
if(i<OldAtomNum)
{
Atoms[i]=NewAtoms[i];
continue;
}else if(OldAtomNum!=0 && i==OldAtomNum){
delete[] NewAtoms;
}
Atoms[i].location=Begin;
Atoms[i].velocity=vect(0,0,0);
Atoms[i].location.X+=(i-OldAtomNum)*distance;
randnum=error*(float(rand()%201-100)/200);
Atoms[i].location.X+=distance*randnum;
randnum=error*(float(rand()%201-100)/200);
Atoms[i].location.Y+=distance*randnum;
randnum=error*(float(rand()%201-100)/200);
Atoms[i].location.Z+=distance*randnum;
Atoms[i].radius=1;
Atoms[i].mass=1;
Atoms[i].ID=i;
}
}