Forum Informatyka UJ forum Strona Główna Informatyka UJ forum
Rocznik 2005 - czyli najlepsze forum w sieci
 
 FAQFAQ   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy   GalerieGalerie   RejestracjaRejestracja 
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

Problem z implementacją Pascal'owego var w C++..:(

 
Napisz nowy temat   Odpowiedz do tematu    Forum Informatyka UJ forum Strona Główna -> Archiwum / 1 rok / 2 i 3 semestr - Programowanie
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
::Reksio::
pijak



Dołączył: 01 Kwi 2006
Posty: 174
Przeczytał: 0 tematów


PostWysłany: Sob 13:08, 10 Cze 2006    Temat postu: Problem z implementacją Pascal'owego var w C++..:(

Mam taki mały problem, który zapewne jest problemem tylko w sferze mojej głębokiej nieznajomości C++, ale na tym to właśnie etapie skutecznie uniemożliwia mi jakąkolwiek pracę przy pisaniu projektu..:/ Otóż problem jest następujący:

Jak w C++ zaimplementować coś takiego:

Cytat:

1.....Type
2........pLeaf=^Leaf;
2........Leaf=record
3....................value: integer;
4....................left:pLeaf;
5....................right:pLeaf;
6................end;
7.
8...Var
9.....Procedure Insert(var pointer:pLeaf, value:integer)
10.......begin
11...........if pointer <> nil then
12...............begin
13...................if value < pointer^.value then
14.......................Insert(pointer^.left,value)
15...................else
16.......................begin
17...........................if value > pointer^.value then
18...............................Insert(pointer^.right,value)
19...........................else
20...............................writeln('ERROR');
21.......................end;
22...............end
23...........else
24...............begin
25...................new(NewLeaf);
26...................NewLeaf^.value:=value;
27...................NewLeaf^.left:=nil;
28...................NewLeaf^.right:=nil;
29...................pointer:=NewLeaf;
30...............end;
31.......end;


Procedura Insert(dostając przy pierwszym wywołaniu Head jako parametr, czyli głowę/korzeń drzewa) korzysta z przekazywania przez adres wskaźnika pointer, dzięki czemu jest o tyle sprytna, że nie potrzebuje sprawdzać czy drzewo jest puste, bo ZAWSZE "podmienia" napotkanego nil'a na adres nowego liścia..

Jak to zaimplementować w C++ przy wykorzystaniu klasy Leaf..? A konkretnie: JAK WYCIĄGNĄĆ Z KLASY LEAF PRYWATNE WSKAŹNIKI LEFT I RIGHT TAK BY TAKĄ IMPLEMENTACJĘ PRZEPROWADZIĆ..??

Klasa Leaf wygląda u mnie tak:

Cytat:

1....class Leaf
2....{
3........typedef xxx;
4.
5........public:
6............Leaf();
7............~Leaf();
8.
9............int GetValue();
10..........xxx GetLeft();
11..........xxx GetRight();
12.
13..........void SetValue();
14..........void SetLeft();
15..........void SetRight();
16.
17......private:
18..........int itsValue;
19..........xxx itsLeft;
20..........xxx itsRight;
21..};


Szczególnie problematyczne są dla mnie wskazane przez xxx fragmenty kodu.. Co powinny zwracać funkcje GetLeft() i GetRight() oraz jak w takim razie powinna wyglądać implementacja przytoczonej przeze mnie procedury Insert w C++..??

Wiem, że jest już sesja, ale gdyby ktoś znalazł czas i wytłumaczyłby mi to jakoś ładnie i składnie byłbym bardzo wdzięczy, bo sam sobie na te pytanie nie jestem w stanie odpowiedzieć.. :(
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Rogal
Zjeb z kaszanką



Dołączył: 13 Mar 2006
Posty: 1745
Przeczytał: 0 tematów

Skąd: koło podbiegunowe

PostWysłany: Sob 13:47, 10 Cze 2006    Temat postu:

Co do pól prywatnych itsLeft, itsRight to chyba nie ma wątpliwości że to mają być wskaźniki na klasę Leaf, czyli po prostu Leaf *itsRight, *itsLeft

A co do metod to można to zrobić na dwa sposoby:

1. Ustawić zwracany typ metodom typu Get na referencję do wskaźnika, czyli Leaf *& getLeft() i olać metody typu Set (nie polecam)

2. W metodach get zwracać po prostu wskaźnik do Leaf i korzystać z metod typu Set (polecam)

ponieważ dzisiaj jestem dobrym Rogalem to postanowiłem przepisać Twojego Inserta na C++:
Kod:

#include <cstdio>

class Leaf {
public:
   Leaf();
   ~Leaf();
   int getValue();
   Leaf*& getLeft();
   Leaf*& getRight();
   void setValue(int);
   void setLeft(Leaf*);
   void setRight(Leaf*);
   
   private:
   int itsValue;
   Leaf *itsLeft, *itsRight;
};

void Insert(Leaf*& pointer, int value) {
   if(pointer != 0) {
      if(value < pointer->getValue())
         Insert(pointer->getLeft(), value); else if (value > pointer->getValue())
         Insert(pointer->getRight(), value); else
         printf("ERROR\n");
   } else {
      Leaf* NewLeaf = new Leaf;
      NewLeaf->setValue(value);
      NewLeaf->getLeft()=0;
      NewLeaf->getRight()=0;
      pointer=NewLeaf;
   }
}



Ostatnio zmieniony przez Rogal dnia Sob 14:04, 10 Cze 2006, w całości zmieniany 1 raz
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Robson
zielony żul



Dołączył: 21 Paź 2005
Posty: 1274
Przeczytał: 0 tematów

Skąd: Z Lasu :]

PostWysłany: Sob 13:53, 10 Cze 2006    Temat postu:

Z tego co wiem to
xxx powinien być *Leaf
czyli typedef Leaf *pLeaf

no a te funkcje powinny zwracac referencje do swoich odpowiednich pól.
czyli
GetLeft:
pLeaf & GetLeft() { return Left; };

niestety zwracajac referencje do prywatnych wskaxników klasy niejako odsłaniasz bebechy swojej klasy na widok publiczny (kazdy moze sobie wziac taka referencje a potem na niej mieszac, czyli zamieniac wartosci zmiennej wskazywanej przez referencje). Dlatego drogi są dwie aby zachować enkapsulacje:
1. Zwracac wsyztsko przez referencje, ale klase Leaf zrobić klasą wewnetrzna i prywatną dla klasy Tree
2. Nie udostepnic zadnych metod składowych publicznych w klasie Leaf ale uczynić klase Tree zaprzyjaznioną z klasa Leaf (w klasie leaf piszesz friend Tree; ), i teraz z klasy Tree masz dostep do wsyztskich pól przywatnych klasy Leaf, i tylko klasa Tree moze sobie na tym manipulować.

Aha w C++ odpowiednikiem var jest &
np
Procedure Insert(var pointer:pLeaf, value:integer)
<=>
void instert(pLeaf & node; int x ); // z dokładnoscia do nazw zmiennych ;)
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
::Reksio::
pijak



Dołączył: 01 Kwi 2006
Posty: 174
Przeczytał: 0 tematów


PostWysłany: Nie 16:09, 11 Cze 2006    Temat postu:

@ Rogal, Robson:

Wielkie dzięki za pomoc.. ;) Doceniam.. ;) Niestety chyba przesadziłem z rozmachem pzeprowadzonych zmian w algorytmach z Cormena (jak zwykle :D ), więc chyba jednak powrócę do pierwowzoru, a z referencjami w klasach poznam się bliżej przez wakacje..;) Ale dziękuję bardzo za pomoc!.. ;)
Powrót do góry
Zobacz profil autora
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
Robson
zielony żul



Dołączył: 21 Paź 2005
Posty: 1274
Przeczytał: 0 tematów

Skąd: Z Lasu :]

PostWysłany: Nie 17:09, 11 Cze 2006    Temat postu:

Aha a tak wracając do tego co Rogal napisał -> to metody Get i Set są zeczywiście najlepsze - najbardziej obiektowo orientowane ;) ... o tym zapomniałem :oops:
Polecam więc za Rogalem: piszcie akcesory Get i Set :)
Powrót do góry
Zobacz profil autora
Wyświetl posty z ostatnich:   
Napisz nowy temat   Odpowiedz do tematu    Forum Informatyka UJ forum Strona Główna -> Archiwum / 1 rok / 2 i 3 semestr - Programowanie Wszystkie czasy w strefie EET (Europa)
Strona 1 z 1

 
Skocz do:  
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach

fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001, 2005 phpBB Group
Regulamin