• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

obiekt w klasie i jego widoczność poza klasą

0 głosów
591 wizyt
pytanie zadane 24 lutego 2018 w Mikrokontrolery przez Paweł Dymek Bywalec (2,300 p.)
edycja 24 lutego 2018 przez Paweł Dymek

Witam.

Mam sobie klasę:

class C
{
    int z1;
    int z2;
    struct S;
    S *obj;
    
    public:
    C(ile,z11,z12);
    
}

class obiektyC
{
    static C **objC;
    static void createObjTab(int ile);
    
}
struct C::S
{
    int a;
    int b;
}
C::C
{
    C(ile,z11,z12);
    {
        obj=new S[ile];
        z1=z11;
        z2=z12;
    }
}
void obiektyC::createObjTab
{
    static void createObjTab(int ile)
    {
        objC= new *C[ile];
        
    }
}
...

for(int a=0;a<wielkosc_tablicy_powyzej;a++)    
    C+a=new C(1,3);//do wszystkich elementów tablicy wskazników na obiekty typu C przypisuje nowe elementy tego typu

    
void test()
{
    (*(obiektyC::C+1))-> z1;
    (*(obiektyC::C+1))-> obj+1 ->a;
}

 i teraz przy kompilowaniu w funkcji test kompilator widzi zmienną z1 i nic nie mówi, ale już obiektu 'obj' utworzonego na podstawie struktury nie widzi i wywala 'obj' was not declared in this scope.

 

 

To nie jest mój oryginalny kod, bo jest on za duży i porozkładaniy na pliki h i cpp dlatego jedynie ideę przepisałem.

Jeśli są tu jakieś drobne błędy w kodzie to nieważne, pisałem to z głowy tylko aby pokazać zarys.

2 odpowiedzi

0 głosów
odpowiedź 24 lutego 2018 przez Wiciorny Ekspert (283,300 p.)

Program wykonywany jest kaskadowo linijka po linijce, jak ma byc w takim razie utworzony obiekt? skoro masz tylko jego deklaracje i definicje ?

deklaracja  wskaźnika to jest tylko

    S *obj;

a to jest tylko definicja ( poniżej ) , ale żadna instancja nie powstała jeszcze 

struct C::S
{
    int a;
    int b;
}
 

np w ten sposób

   S *obj  = new S(); // tworzysz obiekt, wskaźnik na strukture 

Co inego zmienna, gdyż zmienna to tylko utworzenie miejsca w pamięci o danym typie stąd wystarcza deklaracja, ponieważ inicjalizacje zachowujesz w konstruktorze 

C(z11,z12)
    {
        z1=z11;
        z2=z12;
    }
// tu zachodzi inicjalizacja zmiennych 

 

komentarz 24 lutego 2018 przez Paweł Dymek Bywalec (2,300 p.)
zamieszałem, zedytowałem głowny post i teraz powinno byc blizej tego co mam, tworzę tablice obiektów typu S w konstruktorze obiektu C, zatem one są już utworzone
komentarz 24 lutego 2018 przez Wiciorny Ekspert (283,300 p.)
 C(ile,z11,z12);
    {
        obj=new S[ile];
        z1=z11;
        z2=z12;
    }

a skąd program ma wiedzieć o który obj Ci chodzi  skoro obj jest tylko wskaźnikiem na strukture...? 

Każda instancja klasy będzie miała inny obj.  sprawdź  słowo kluczowe 'this'

  obj=new S[ile];

tutaj wskaźnikowi przypisujesz strukturę... ale najpierw ten wskaźnik trzeba powiązać z instancją 

  S *obj;

wskazujesz na coś co nie istnieje... 

komentarz 24 lutego 2018 przez Paweł Dymek Bywalec (2,300 p.)
S *obj; //Tworzę wskaźnik na obiekt typu S

..

obj = new S[ile]; //tworzę tablicę ile-elementową obiektów typu S, od teraz obj przechowuje wskaźnik na pierwszy element tej tablicy


 

Co tu jest źle?

komentarz 24 lutego 2018 przez Wiciorny Ekspert (283,300 p.)
S *obj; //Tworzę wskaźnik na obiekt typu S
 

wskaźnik na obiekt typu S. Zatem-  nie tworzysz obiektu :) typu S... ale referencje do niego

a w tym miejscu tej referencji :  ( referencji która jest pusta ) przypisujesz nowe obiekty ....

obj = new S[ile];

dodatkowo własnie obj- wskazywać bedzie na strukture a przypisujesz mu tablice struktur... tak nie możesz 

komentarz 24 lutego 2018 przez Paweł Dymek Bywalec (2,300 p.)
edycja 24 lutego 2018 przez Paweł Dymek

Zgłupiałem. Przecież to jest najzwyklejsze dynamiczne alokowanie pamięci, nie przypisuje mu tablicy struktur tylko dynamicznie alokuje pamięć na tablicę obiektów S o wielkości ile. 

dodatkowo własnie obj- wskazywać bedzie na strukture a przypisujesz mu tablice struktur... tak nie możesz 

obj będzie wskazywał na pierwszy obiekt w tablicy obj

obj nie może wskazywać na strukture, bo ta defacto nie jest żadnym bytem, nie istnieje. Istnieje tylko obiekt utworzony wg jej przepisu, a dokładnie tablica tych obiektów dla której zarezerwowałem dynamicznie pamięć.


#include <iostream>

using namespace std;
struct S
{
    int a;
    int b;
};
int main()
{
    S * myStr;
    myStr= new S[2];//dynamiczne zaalokowanie pamięci dla tablicy obiektów typu S
    cout<<"czy mają one kolejne adresy pamięci?"<<endl;
    cout<< myStr <<endl;
    cout<< myStr+1 <<endl;
    // teraz operacje na zmiennych w tych obiektach:
    myStr->a=1;
    myStr->b=2;
    (myStr+1)->a=3;
    (myStr+1)->b=4;
    cout<< myStr->a <<endl;
    cout<< myStr->b <<endl;
    cout<< (myStr+1)->a <<endl;
    cout<< (myStr+1)->b <<endl;
    
    return 0;
}

Rezultat:

0x12dbc20                                                                                                                                                                          
0x12dbc28                                                                                                                                                                          
1                                                                                                                                                                                  
2                                                                                                                                                                                  
3                                                                                                                                                                                  
4  

Jak widać adresy są po kolei 

0x12dbc20 0x12dbc28

8 bajtów bo obiekt ma dwa inty po 4 bajty, operacje na zmiennych w obiektach też działają, nie moge zrozumieć gdzie mam błąd.

0 głosów
odpowiedź 24 lutego 2018 przez Paweł Dymek Bywalec (2,300 p.)

Po wielu godzinach doszedłem jaki błąd był banalny, wyjaśnię jakby ktoś podobny problem napotkał:

 

(*(obiektyC::C+1))-> z1;

to działa bo:

(*(obiektyC::C+1)) wskazuje na wskaźnik na obiekt klasy C i dalej uzywajac operatora wyluskania dostajemy sie do obiektu po jego lewej stronie a po prawej jest zmienna z1, która tam istnieje - tu wszystko bylo ok

(*(obiektyC::C+1))-> obj+1 ->a;

tu jest błąd w zapisie, bo:

wskaznik na obiekt typu C:

(*(obiektyC::C+1))

wyłuskany opbiekt typu C:

(*(obiektyC::C+1)) ->

wskaźnik na pierwszy obiekt w tablicy obiektów typu S w obiekcie typu C:

(*(obiektyC::C+1)) -> obj

wskaźnik na drugi obiekt w tablicy obiektów typu S w obiekcie typu C:

((*(obiektyC::C+1)) -> obj)+1

drugi obiekt w tablicy obiektów typu S w obiekcie typu C:

(((*(obiektyC::C+1)) -> obj)+1)->

zmienna a w drugim elementcie tablicy obiektów typu S w obiekcie typu C

(((*(obiektyC::C+1)) -> obj)+1)->a

 

i działa jak natura chciała :)

 

Dziękuję za każdy post odpowiedzi w temacie :)

 

 

Podobne pytania

0 głosów
1 odpowiedź 849 wizyt
pytanie zadane 11 marca 2018 w C i C++ przez zpawlo00 Początkujący (310 p.)
0 głosów
1 odpowiedź 811 wizyt
0 głosów
1 odpowiedź 256 wizyt
pytanie zadane 5 stycznia 2019 w PHP przez roxy32l Początkujący (470 p.)

93,741 zapytań

142,677 odpowiedzi

323,296 komentarzy

63,326 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...