Ĺadny brzuch
Witam:) Jestem studentem pierwszego roku informatyki. W związku ze zbliżającym się kolokiwium z Programowania w języku C++, postanowiłem sobie trochę przed nim poćwiczyć. Napisałem sobie kawałek przykladowej klasy:
class CFoo { private: int m_nPole; public: CFoo(int nPole = 45) : m_nPole(nPole) { } //{ m_nPole = nPole; } int Pole() const { return m_nPole; } };
i terez chciałbym stworzyć różne warianty tablicy z istancjami tej klasy
a)zwykła tablica z obiektami
Więc piszę sobie tak:
CFoo aTablica[100];
Ok-tylko teraz jak zrobić aby np aby pola obiektów w tej tablicy(m_nPole) mialy wartosci od 1 do 100 tzn pole w pierwszym obiekcie bylo rowne 1, pole w drugim obiekcie bylo rowne 2 itd?
b)tablica jak w porzednim przykladzie ale ze wskaznikami na obiekty, bo potem do tych wskaznikow chce podpiąć za pomocą operatora new jakies przykladowe obiekty
więc robię tak:
alokuję pamieć:
CFoo* aTablica[100];
a potem w pętli do każdego wskaznika przypinam nowy element, coś tam z nim robię i potem usuwam dany wskaznik i a na końcu całą tablicę:
for(int i = 0; i < 100; i++)
{
aTablica[i] = new CFoo(i);
cout << aTablica[i]->Pole() << endl;
delete aTablica[i];
}
delete [] aTablica;
tylko pojawia się waring przy kompilacji: deleting array `CFoo*aTablica[100]' nie za bardzo wiem o co może w nim chodzić:/ przecież kasuję poszczególne obiekty a potem całą tablicę
c)dynamiczna tablica z obiektami
CFoo* aTablica = new CFoo [100]; ale znów nie mogę zainiciować poszczególnych obiektów z osobna:/ ogólnie rzecz biorąc chyba tak się zrobić nie da, ale gdzieś czytałem, że za pomocą listy inicializycyjnej się da ale nie wiem jak to zrobić? Wie może ktoś?
d)no i ostatni wariant tzn dynamiczna tablica ze wsakaznikami do obiektów, a potem przypięcie do tych wskazników jakiś obiektów za pomocą new, Tego wogóle nie mam pojęcia jak to zrobić chociaż próbowałem różnych wersji typu CFoo** aTablica = new CFoo [100] ale wtedy tworzy mi wsk na wsk na tablice z obiektami a ja chcę żeby była tablica ze wskaznikami.
Uhhh, długi ten trochę post, ale bardzo mi zależy żeby się tego wszystkiego co napisałem dowiedzieć, nie tylko ze wzgledu na kolowium ale i ze wględu na to, że mnie to interesuje jak to zrobić :) .
Za wszelką pomoc serdecznie dziękuję.
Co do ostatniego pytania, to:
int main ( int, char** ) { A **dynarr = NULL; dynarr = new A* [10]; for (int i = 0; i < 10; i ++ ) dynarr [i] = new A(); for (int i =0; i < 10; i ++ ) delete dynarr [i]; delete [] dynarr; return 0; }
a)
Hmm...
Tworzysz funkcję klasy (nie konstruktor), która przypisuje podaną wartość dla zmiennej prywatnej m_nPole. Następnie w pętli każdemu obiektowi wpisujesz kolejne wartości od 1 do 100.
Ok, dzięki za pomoc :)
b)tablica jak w porzednim przykladzie ale ze wskaznikami na obiekty, bo potem do tych wskaznikow chce podpiąć za pomocą operatora new jakies przykladowe obiekty
więc robię tak:
alokuję pamieć:
CFoo* aTablica[100];
.
.
.
delete [] aTablica;
tylko pojawia się waring przy kompilacji: deleting array `CFoo*aTablica[100]' nie za bardzo wiem o co może w nim chodzić:/ przecież kasuję poszczególne obiekty a potem całą tablicę
aTablica jest tablicą statyczną. Nie usuwa się tablic statycznych poprzez operator delete.
Wykasuj linijkę
delete [] aTablica;
i będzie git
Ok, jeszcze raz dzięki :) Mam jeszcze jedno pytanie nie dotyczące bezpośrednio tego tematu - piszę tutaj bo nie chcę zakładać nowego tematu. Jak przeciążyć dwukrotnie operator [] ? tzn mam takie cos:
class CMacierz { private: float** pfTab; // wskaznik przechowujacy adres macierzy int n; // rozmiar macierzy tzn liczba kolumn i wierszy public: CMacierz(int nRozmiar = 1) // tworzy macierz n x n { n=nRozmiar; pfTab = new float* [nRozmiar]; for(int i=0;i<n;i++) { pfTab[i] = new float; } } ~CMacierz() { delete [] pfTab; } // usuwa macierz // metody dostepowe do pol macierzy float& operator[][](int i,int j) { return pfTab[i][j]; } // ***TUTAJ*** }; .... CMacierz JakasMacierz(5);
i chce w kodzie odwoływać się do tablicy pfTab poprzez np JakasMacierz[5][3] ? Bo tam jak zaznaczyłem w kodzie to pojawia bład, że nieprawidłowa składnia, a jak dam pojedyńczy nawias to ten operator wtedy przyjmuje tylko jeden parametr i wtedy też wyskakuje błąd. Proszę o szybką odp
Wychodzi błąd bo w C++ nie ma czegoś takiego jak operator podwójnych nawiasów kwadratowych. Istnieje tylko operator pojedynczy. Oczywiście można uzyskać wynik jakiego oczekujesz. Weź pod uwagę, że tab[3] to to samo co *(tab+3). Idąc dalej tą drogą wychodzi też, że tab[3][2] to to samo co *(*(tab+3)+2). Dzięki tej właściwości wskaźników i możliwości przemieszczania się w pamięci, możesz zapisać operator[] tak, żeby nie zwracał konkretnego elementu z tablicy 2 wymiarowej, ale żeby zwracał i-ty wiersz (wskaźnik na i-ty wiersz), a drugi nawias [] wygeneruje się sam zgodnie z poprzednimi uwagami:float* operator[](int i) { return pfTab[i]; }
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
class CFoo { private: int m_nPole; public: CFoo(int nPole = 45) : m_nPole(nPole) { } //{ m_nPole = nPole; } int Pole() const { return m_nPole; } };
i terez chciałbym stworzyć różne warianty tablicy z istancjami tej klasy
a)zwykła tablica z obiektami
Więc piszę sobie tak:
CFoo aTablica[100];
Ok-tylko teraz jak zrobić aby np aby pola obiektów w tej tablicy(m_nPole) mialy wartosci od 1 do 100 tzn pole w pierwszym obiekcie bylo rowne 1, pole w drugim obiekcie bylo rowne 2 itd?
b)tablica jak w porzednim przykladzie ale ze wskaznikami na obiekty, bo potem do tych wskaznikow chce podpiąć za pomocą operatora new jakies przykladowe obiekty
więc robię tak:
alokuję pamieć:
CFoo* aTablica[100];
a potem w pętli do każdego wskaznika przypinam nowy element, coś tam z nim robię i potem usuwam dany wskaznik i a na końcu całą tablicę:
for(int i = 0; i < 100; i++)
{
aTablica[i] = new CFoo(i);
cout << aTablica[i]->Pole() << endl;
delete aTablica[i];
}
delete [] aTablica;
tylko pojawia się waring przy kompilacji: deleting array `CFoo*aTablica[100]' nie za bardzo wiem o co może w nim chodzić:/ przecież kasuję poszczególne obiekty a potem całą tablicę
c)dynamiczna tablica z obiektami
CFoo* aTablica = new CFoo [100]; ale znów nie mogę zainiciować poszczególnych obiektów z osobna:/ ogólnie rzecz biorąc chyba tak się zrobić nie da, ale gdzieś czytałem, że za pomocą listy inicializycyjnej się da ale nie wiem jak to zrobić? Wie może ktoś?
d)no i ostatni wariant tzn dynamiczna tablica ze wsakaznikami do obiektów, a potem przypięcie do tych wskazników jakiś obiektów za pomocą new, Tego wogóle nie mam pojęcia jak to zrobić chociaż próbowałem różnych wersji typu CFoo** aTablica = new CFoo [100] ale wtedy tworzy mi wsk na wsk na tablice z obiektami a ja chcę żeby była tablica ze wskaznikami.
Uhhh, długi ten trochę post, ale bardzo mi zależy żeby się tego wszystkiego co napisałem dowiedzieć, nie tylko ze wzgledu na kolowium ale i ze wględu na to, że mnie to interesuje jak to zrobić :) .
Za wszelką pomoc serdecznie dziękuję.
Co do ostatniego pytania, to:
int main ( int, char** ) { A **dynarr = NULL; dynarr = new A* [10]; for (int i = 0; i < 10; i ++ ) dynarr [i] = new A(); for (int i =0; i < 10; i ++ ) delete dynarr [i]; delete [] dynarr; return 0; }
a)
Hmm...
Tworzysz funkcję klasy (nie konstruktor), która przypisuje podaną wartość dla zmiennej prywatnej m_nPole. Następnie w pętli każdemu obiektowi wpisujesz kolejne wartości od 1 do 100.
Ok, dzięki za pomoc :)
b)tablica jak w porzednim przykladzie ale ze wskaznikami na obiekty, bo potem do tych wskaznikow chce podpiąć za pomocą operatora new jakies przykladowe obiekty
więc robię tak:
alokuję pamieć:
CFoo* aTablica[100];
.
.
.
delete [] aTablica;
tylko pojawia się waring przy kompilacji: deleting array `CFoo*aTablica[100]' nie za bardzo wiem o co może w nim chodzić:/ przecież kasuję poszczególne obiekty a potem całą tablicę
aTablica jest tablicą statyczną. Nie usuwa się tablic statycznych poprzez operator delete.
Wykasuj linijkę
delete [] aTablica;
i będzie git
Ok, jeszcze raz dzięki :) Mam jeszcze jedno pytanie nie dotyczące bezpośrednio tego tematu - piszę tutaj bo nie chcę zakładać nowego tematu. Jak przeciążyć dwukrotnie operator [] ? tzn mam takie cos:
class CMacierz { private: float** pfTab; // wskaznik przechowujacy adres macierzy int n; // rozmiar macierzy tzn liczba kolumn i wierszy public: CMacierz(int nRozmiar = 1) // tworzy macierz n x n { n=nRozmiar; pfTab = new float* [nRozmiar]; for(int i=0;i<n;i++) { pfTab[i] = new float; } } ~CMacierz() { delete [] pfTab; } // usuwa macierz // metody dostepowe do pol macierzy float& operator[][](int i,int j) { return pfTab[i][j]; } // ***TUTAJ*** }; .... CMacierz JakasMacierz(5);
i chce w kodzie odwoływać się do tablicy pfTab poprzez np JakasMacierz[5][3] ? Bo tam jak zaznaczyłem w kodzie to pojawia bład, że nieprawidłowa składnia, a jak dam pojedyńczy nawias to ten operator wtedy przyjmuje tylko jeden parametr i wtedy też wyskakuje błąd. Proszę o szybką odp
Wychodzi błąd bo w C++ nie ma czegoś takiego jak operator podwójnych nawiasów kwadratowych. Istnieje tylko operator pojedynczy. Oczywiście można uzyskać wynik jakiego oczekujesz. Weź pod uwagę, że tab[3] to to samo co *(tab+3). Idąc dalej tą drogą wychodzi też, że tab[3][2] to to samo co *(*(tab+3)+2). Dzięki tej właściwości wskaźników i możliwości przemieszczania się w pamięci, możesz zapisać operator[] tak, żeby nie zwracał konkretnego elementu z tablicy 2 wymiarowej, ale żeby zwracał i-ty wiersz (wskaźnik na i-ty wiersz), a drugi nawias [] wygeneruje się sam zgodnie z poprzednimi uwagami:float* operator[](int i) { return pfTab[i]; }