Skocz do zawartości

[C++] programowanie obiektowe


Jaklub

Rekomendowane odpowiedzi

postanowiłem kolejny mój projekt przenieść na C++. tym razem jednak zabieram się za to na poważnie. wcześniech wszystko robiłem na tablicach (możecie się śmiać), ale teraz postanowiłem nauczyć się programowania obiektowego.

1. składniki statyczne? ossochosi?

2. domyślam się, że gdy natrzaskam sobie obiektów danej klasy, żeby np. ustawić u wszystkich wskazaną zmienną na 3 lub wywołać funkcję, muszę je przelecieć pętlą. no właśnie, gdzie je porozmieszczać? na tablicy? wydaje mi się, że nie jest to dobre rozwiązanie, więc pytam

 

halp

Odnośnik do komentarza
Udostępnij na innych stronach

2. to zalezy czy liczba elementow bedzie stala czy zmienna. jak stala (np. kafle terenu) to uzywasz tablic, jak zmienna (np. pociski/potworki) to list. Plusem jest ze masz dostepne gotowe kontenery do tego, takie jak std::vector i std::list, i nie musisz pisac wlasnych.

Odnośnik do komentarza
Udostępnij na innych stronach

1. Składniki statyczne - funkcje/metody/obiekty które są globalne

2. Nie ważne czy użyjesz vector/list, jakiś loop musi się znaleźć, aby te obiekty updateować/rysować :)

U list szybciej działa metoda tworzenia i usuwania, wolniej działa iteracja, ponieważ obiekty w liście są ustawiane 'chaotycznie' tzn. każdy obiekt ma 'losowe' miejsce w pamięci.

Natomiast vectory wolniej działają przy usuwaniu, czy dodawaniu obiektów, jednak ich iteracja jest dużo szybsza, ponieważ obiekty w vectorze są ustawiane równomiernie w puli pamięci. Uwaga! Przy każdym dodawaniu/usuwaniu obiekty w vectorze są kopiowane i usuwane ( 'Stare' obiekty ) do innego miejsca w pamięci ( Mogą wystąpić problemy z wskaźnikami )!

Odnośnik do komentarza
Udostępnij na innych stronach

dzięki za odpowiedzi.

postanowiłem użyć vectorów. tylko jest jeszcze jeden, co tu mówić, duży problem - jak to obsługiwać?

wykombinowałem taki oto kod:

#include <cstdlib>
#include <vector>
#include <iostream>

using namespace std;

class Cake
{
      public:
      int a;
};

vector < Cake* > lista;

int main(int argc, char *argv[])
{
    Cake *temp = new Cake();
    lista.push_back(temp);
    temp=NULL;
    temp = new Cake();
    lista.push_back(temp);
    temp=NULL;
    // ^ tak jeszcze dwa razy
    
    vector<Cake*>::iterator iter=lista.begin();
    *iter->a=3;
    iter++;
    // dajemy tak parę wartości
    //cout << *iter << endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}

skrócony kod

nie działa, błąd na "*iter->a=3;". bezmyślne zamiany na "**iter->a=3;", "iter->a=3;" i "*iter.a=3" nie dają efektu. nigdy nie umiałem dobrze używać wskaźników i są efekty. pomóżcie... znowu. plizzz

Odnośnik do komentarza
Udostępnij na innych stronach

std::vector traktujesz jak zwykłą tablicę jednowymiarową, czyli:

vector<Cake*> lista;
lista.push_back(new Cake());
for(int i=0;i<lista.size();i++)
if(lista[i]!=NULL)
lista[i]->a=3;

Odnośnik do komentarza
Udostępnij na innych stronach

Najlepiej traktuj wektor jak zwykła tablice jeśli chodzi o alokacje czyli:

 

vector<Cake> wek(100);

 

potem:

 

wek[x].c=y;

 

Nie lubisz wskaźników więc nie ma co ich wpychać tam gdzie ich nie potrzeba.

Poza tym taka rada nie dawaj żadnych składowych jako publicznych! Niby prosty program ale warto od początku się przyzwyczajać.

 

*iter->a=3; poprawna forma to: (*iter)->a=3;

 

2. domyślam się, że gdy natrzaskam sobie obiektów danej klasy, żeby np. ustawić u wszystkich wskazaną zmienną na 3 lub wywołać funkcję, muszę je przelecieć pętlą. no właśnie, gdzie je porozmieszczać? na tablicy? wydaje mi się, że nie jest to dobre rozwiązanie, więc pytam

Jeśli znasz max rozmiar i nie będziesz potrzebował jakiś dodatkowych funkcji do operowania na danych,które ma vector/lista/kolejka itd lub będą to funkcje stworzone przez Ciebie możesz użyć tablic no problem.

Odnośnik do komentarza
Udostępnij na innych stronach

po objęciu *iter w nawias działa. metoda ΨΧΞ też działa. thx.

teraz został tylko jeszcze jeden problem.

chcę zwolnić pamięć po obiekcie. am i doing it rite

deklaracja klasy

class Cake
{
      public:
      int a;
      Cake();
      virtual ~Cake();
};
Cake::Cake() {
             a=0;
}
Cake::~Cake() {
              delete &a;
}

i kasowanie obiektu

    lista[1]->~Cake();
    lista.erase(lista.begin()+1);

kompiluje się i wywala z listy (a właściwie vectora), ale chcę się upewnić, czy to będzie zwalniało pamięć

Odnośnik do komentarza
Udostępnij na innych stronach

kasowanie dokonujesz operatorem delete nie zas wywolywaniem destruktora, bo on tylko wykonuje sie podczas wlasnie wywolania delete;

delete lista[1];
lista.erase(lista.begin()+1);

Odnośnik do komentarza
Udostępnij na innych stronach

kasowanie dokonujesz operatorem delete nie zas wywolywaniem destruktora, bo on tylko wykonuje sie podczas wlasnie wywolania delete;

delete lista[1];
lista.erase(lista.begin()+1);

czyli potraktowanie elementu za pomocą delete załatwi sprawę i przy tym wywali mi wszystkie elementy obiektu?

Odnośnik do komentarza
Udostępnij na innych stronach

delete kasuje cala pamiec zajmowana przez obiekt oraz wywoluje destruktor, czyli zrobi to co chcesz uzyskac

Odnośnik do komentarza
Udostępnij na innych stronach

Używając operatora delete na obiekcie zaalokowanym na stercie dzieje się coś takiego:

-tworzysz sobie jakiś tam string

string *str=new string();


-za jakiś czas go usuwasz
delete ps;  


Następnie "delete ps" zamieniany jest na:

str->~string();                  
operator delete(str); 

więc nie musisz jawnie wywoływać destruktora.

 

class Cake
{
      public:
      int a;
      Cake();
      virtual ~Cake();
};
Cake::Cake() {
             a=0;
}
Cake::~Cake() {
              delete &a;
}

 

Dla własnej wygody i dla dobra innych:

 

#file Cake.h

class Cake
{
public:
     
      Cake();

      virtual ~Cake();

          int getA() const {return a;}
private:

          int a;
};


#file Cake.cpp

Cake::Cake():a(1)
{

}

Cake::~Cake()
{

}

 

kompiluje się i wywala z listy (a właściwie vectora), ale chcę się upewnić, czy to będzie zwalniało pamięć

Masz spore problemy z podstawami, dorwij się do jakiegoś tutka bo będziesz sporo czasu tracił na głupie błędy. Najlepiej na razie odpuść sobie wektory/listy i inne pojemniki z biblioteki standardowej i poćwicz podstawy na pewno na tym nie stracisz a zaoszczędzisz sporo czasów i nerwów.

Odnośnik do komentarza
Udostępnij na innych stronach

dzięki za odpowiedzi.

Masz spore problemy z podstawami, dorwij się do jakiegoś tutka bo będziesz sporo czasu tracił na głupie błędy. Najlepiej na razie odpuść sobie wektory/listy i inne pojemniki z biblioteki standardowej i poćwicz podstawy na pewno na tym nie stracisz a zaoszczędzisz sporo czasów i nerwów.

narazie jestem w trakcie czytania kursów (C i C++) na wikibooks, aby nadrobić zaległości (a to, że dotyczyły przede wszystkim wskaźników i zarządzania pamięcią, to już przykry zbieg okoliczności). ALE wektorów sobie nie odpuszczam. wiem, że umieszczenie tam samych obiektów może nie być zbyt dobrym pomysłem, dlatego postanowiłem użyć wskaźników, chociaż moje pojęcie o nich jest jeszcze blade.

 

btw. nie wciskaj tyle razy enter przy pisaniu kodu. to jest forum i uważam, że to wygląda nieprzejrzyście. ;p

Odnośnik do komentarza
Udostępnij na innych stronach

Między przerwy wstawisz sobie komentarze ;)

 

 

ALE wektorów sobie nie odpuszczam. wiem, że umieszczenie tam samych obiektów może nie być zbyt dobrym pomysłem, dlatego postanowiłem użyć wskaźników, chociaż moje pojęcie o nich jest jeszcze blade.

To wcale nie jest głupi pomysł. Defaultowy alokator nie jest wydajny dla małych obiektów. To co jest dostępne defaultowo w c++ to proste wrappery na (malloc/realloc/ free) z C, który nie jest przystosowany do alokacji małych obiektów i każda alokacja pochłania dodatkowo 4 to 32 bytes pamięci więc jeśli dajmy alokujesz obiekt Cake na stercie to masz overhead minimum 100% a w najgorszym wypadku masz 32+2 bytes(wtf?!)[ nie brałem tutaj typu int tylko short].

 

Jak wcześniej pisałem jeśli nie trzeba używać pamięci alokowanej na stercie, równie dobrze możesz mieć wektor obiektów:

vector<object> wek(100);

 

Dodawanie ma jakiś tam większy narzut bo trzeba wywołać konstruktor kopiujący ale jeśli dane klasy posiadają tylko szereg typów wbudowanych nie jest to wielkim problemem. Wszystko zależy od tego co chcesz tam wepchać.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...