[c++] odwołanie się do zmiennej z innego obiektu

0

Witam serdecznie,

Dopiero ucze sie C++ dlatego prosze o wyrozumialosc.
Caly czas probuje zrozumiec obiektowosc w C++, szczerze mowiac mam sporo problemow..
Mam nadzieje ze znajdzie sie ktos kto mi pomoze:( Z gory dziekuje za czas i poswiecenie dla mnie.

Chce wprowadzic poprawke do programu ktory juz istneje i tak dziala:
Jest 30 obiektow typu Komputer. Kazdy z komputerow ma swoj ID (0-39), i posiada 5 buforow (0-4) w ktorych przechowuje jakies dane ktore przetwarza. Podczas startu dzialania programu do pierwszego Komputera (ID: 0) wprowadzane sa dane kolejno do buforow (0,1,2,3 i 4). Nastepnie do drugiego Komputera (ID:1) do buforow 0 i 1 kopiowane sa dane z ostatnich dwoch buforow (3 i 4) z Komputera pierwszego. Do buforu 2,3 i 4 wprowadzane sa nowe dane. Nastepnie znowu do Komputera trzeciego (ID:2), do buforow 0 i 1 kopiowane sa dane z 3 i 4 bufora z Komputera poprzedniego czyli nr 2.... I tak dalej. Jak proces dojdzie do Komputera nr 39, bufory z Komputera nr 1 zostaja zwolnione i dane sa kopiowane z buforow 3 i 4 ostatniego Komputera do buforow 0 i 1 pierwszego Komputera.

Nie wiem w jaki sposob moge sie skomunikowac z jakas zmienna lub funkcja w innym obiekcie tej samej klasy z poziomu takiego samego obiektu. Np zeby Komputer nr 3 mogl pobrac do siebie wartosc zmiennej przetworzonej przez Komputer nr 2, lub wynik funkcji ktora siedzi w Komputerze nr 2.
Wiadomo ze kazdy z obiektow typu Komputer jest 'stworzony' przez ten sam kod, jednak dziala na roznych danych (w zaleznosci co zostanie wpisane do buforow..) a chodzi mi o to zeby kazdy z nich mial tez mozliwosc komunikacji, pobrania wartosci zmiennej ktora jest przetwarzana przez inny obiekt tego samego typu (tutaj:zmienna w buforze Komputera o numerze rownym ID-1 (Komputer o 1 wczesniej)).

Nie moge sobie tego wyobrazic czy to w ogole jest mozliwe? Moze trzeba zrobic jakas funkcje ktora odwoluje sie w jakis sposob do "siebie" (bo jezeli jest to taki sam obiekt czyli Komputer?) ale o innym numerze (ID Komputera)? Ciezko jest mi to sobie wyobrazic.
Czy ktos juz spotkal sie z takim problemem? Prosze o pomoc.

Nie umieszczam kodu gdyz jest bardzo duzy (kilkanascie plikow *.cpp i *.h).

PS Oczywiscie nie chodzi mi o kod tylko o opis postepowania, moze jakis algorytm (czy trzeba zrobic jakies funkcje, uzyc wskaznikow, referencji... w jaki mniej wiecej sposob). Pozdrawiam!!

0

Taka prosta propozycja: niech obiekt typu Komputer zawiera wskaźnik na następny\poprzedni - zrobić listę dwukierunkową. Ew. nawet jedno - wskaźnik na poprzedni. Obiekty danego typu mają dostęp do wszystkich pól innych obiektów swojego typu bądź podrzędnych\nadrzędnych /oczywiście w drugim wypadktu tylko tych, które obiekt zna/. W sumie ciekawie by się tutaj fabryka prezentowała do tworzenia kolejnych instancji klasy Komputer, ew. jawnie przekazywać w konstruktorze rejerencję na poprzedni utworzony obiekt.

@Ghostek, fakt... ale kontener ten musi być globalny bądź jawnie przekazany do instancji Kontenera aby mogła ona się odwoływać do poprzednika.

0

Hmm? Co w tym takiego trudnego? Trzymasz te komputery w jakimś kontenerze (np. vector z stla) i każdemu ładujesz do buforów zawartość poprzedniego (normalne odwoływanie się do składowych).
EDIT:
Chwilę się człowiek zastanowi nad postem a tu już za późno ;)

0

edit: napisalem sie, potem zauwazylem ze lekko nie na temat, ale co mi tam.. wlasciwe uzycie tych banalow pod spodem rozwiazuje problem

--
od tego sa wlasnie wskazniki i referencje.. jednak najprosciej to pokazac na kodzie

niech bedzie dana klasa, jedna zmienna i jedna metoda, no i konstruktor

class Cos
{
    int x;
public:
    Cos(int wartosc):x(wartosc){}
    void zrobcos(){  /*....*/ }
};

gdzies-tam tworzymy dwa obietkty tej klasy, majace rozne wartosci:

int main()
{   Cos raz(5);
    Cos dwa(10);
}

chcemy, aby metoda ZrobCos powodowala, ze wybrany obiekt "komunikuje sie" z tym drugim, sprawdza jego wartosc, i jesli jest wieksza -- sam sie na taka ustawia. sa 2 opcje: albo ten wskazany obiekt juz musi wczesniej wiedziec, ze "tendrugi" istnieje, albo musi dostac "tegodrugiego" jako argument metody zrobcos..

opcja 2, latwiejsza:

class Cos
{ ...
    void zrobcos(Cos const & tendrugi)
   {   if(x  <  tendrugi.x)   //jesli moje X jest mniejsze od jego X'a
            x = tendrugi.x;    //ustawiam swoje x na takie samo jak tego drugiego
   }
}

ale.. to tylko metoda. trzeba ja odpalic:

int main()
{   Cos raz(5);
    Cos dwa(10);
    Cos trzy(15);

    dwa.zrobcos(raz);    //dwojka "porownuje sie" z jedynka, bez zmian
    raz.zrobcos(trzy);   //jedynka "porownuje sie" z trojka, efekt: jedynka.x==15
    dwa.zrobcos(raz);   //dwojka znow "porownuje sie" z jedynka, efekt: dwojka.x==15
}

plus: prostota uzycia
minus: za kazdym razem trzeba podawac kto-z-kim.. i wyliczac wszystkich

opcja 1, bardziej zlozona -- obiekt "zna" swoich sasiadow

class Cos
{ ...
    Cos* sasiad;

public:
    void ustawSasiada(Cos const& inny){ sasiad = &inny;}

    void zrobcos()
   {   if(x  <  sasiad->x)   //jesli moje X jest mniejsze od jego X'a
            x = sasiad->x;    //ustawiam swoje x na takie samo jak mojego sasiada
   }
}
int main()
{   Cos raz(5);
    Cos dwa(10);
    Cos trzy(15);

    raz.ustawSasiada(trzy);    //jedynka bedzie sie porownywac z trojka
    dwa.ustawSasiada(raz);    //za dwojka z jedynka

    dwa.zrobcos();    //dwojka "porownuje sie" z-sama-wie-kim, bez zmian
    raz.zrobcos();    //jedynka "porownuje sie" z-sama-wie-kim, efekt: jedynka.x==15
    dwa.zrobcos();   //dwojka znow "porownuje sie" z-sama-wie-kim, efekt: dwojka.x==15
}

jak widac, drugi sposob to dwie 'fazy': "przygotowanie" i "praca". ale dzieki temu, pozniej wszystko jest bardziej hm... automatyczne. oczywiscie -- kazdy obiekt moze pamietac wiecej niz jednego sasiada, moze miec "polaczenia" z dowolna ich iloscia..

..i oczywisce uwaga ze wskaznikami.. w przykladach bralem adres zmiennych lokalnych, bo wszystkie mialy ten sam scope, wiec bylo to bezpieczne..

0

Super o to mi chodzilo! Dzieki wielkie za przyklad! Powoli wszystko zaczynam rozumiec... z czym to sie je :)

Mam jednak nadal problemy:(

Obiekty (Komputer ID: 1, 2, ... , 39) tworzone sa w osobnym pliku *.cpp, (ktory nie posiada pliku naglowkowego *.h) czyli nie mam mozliwosci uzywania nazw tworzonych obiektow, wiec takze nie udaje mi sie odwolywac w funkcji (dzieki ktorej mialbym sie komunikowac z innym Komputerem) do nazwy stworzonego obiektu - a co za tym idzie do ich zmiennych:(
Jest jakis sposob zeby to obejsc? Bardzo prosze o dalsza pomoc i ew. super-pomocne (naprawde :)) przyklady.

Z gory dzieki wielkie!

0
deus napisał(a)

@Ghostek, fakt... ale kontener ten musi być globalny bądź jawnie przekazany do instancji Kontenera aby mogła ona się odwoływać do poprzednika.

Ja bym posłał iterator, a w wypadku listy to może nawet i na chama wskaźnik (chociaż musiałbym wpierw przejrzeć <list> coby się upewnić, czy lista aby na pewno nie rusza swoich elementów). Albo przechowywałbym w kontenerze wskaźniki, wtedy przekazanie do obiektu takowego byłoby już w pełni legalne ;)

EDIT:
@studentt -> kilka propozycji:

  1. nie możesz po prostu dorobić tego nagłówka?
  2. ja bym tam mimo wszystko posłużył się kontenerem, np: (zakładając, że Komputer jest zdefiniowany podobnie jak Cos z kodu quetzalcoatla)
vector<Komputer*> komputery;
(...) // wypełnienie kontenera Komputerami itp
for(int i=1; i<komputery.size(); i++) komputery[i]->ustawSasiada(komputery[i-1]);
komputery[0]->ustawSasiada(komputery[komputery.size()-1)];
(...)

EDIT2:
Jakby co (nie wiem na jakim etapie nauki C++ jesteś), wypełnić kontener możesz np. tak:

komputery.resize(39);
komputery[0] = new Komputer( /* parametry dla konstruktora */ );
(...)
komputery[38] = new Komputer( /* parametry dla konstruktora */ );

Potem musisz po sobie posprzątać:

for(int i=0; i<komputery.size(); i++) delete komputery[i];

1 użytkowników online, w tym zalogowanych: 0, gości: 1