Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Wann sind Folgezeiger sinnvoll?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
28.12.2007, 20:17 Uhr
~Popp
Gast


Hallo,

wann ist in OOP ein Folgezeiger in einer Klasse sinnvoll? Ich hab das noch nirgends gelesen wann und wo man die einsetzen sollte

Bitte um Aufklärung

Gruß

Popp
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
28.12.2007, 22:32 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


was verstehst du unter "Folgezeiger"? Mach maln beispiel was du meinst
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
29.12.2007, 12:13 Uhr
~Popp
Gast


Naja mit folgezeigern meine ich im objekt zeiger auf das nächste objekt z. B.


C++:
class test
{
private:
test* folgezeiger;
public:
[...]
};



wann ist sowas sinnvoll?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
29.12.2007, 12:37 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


sowas macht man zum Beispiel bei verketteten Listen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
29.12.2007, 14:06 Uhr
0xdeadbeef
Gott
(Operator)


Wenn ich richtig verstehe, was du meinst, dann macht man sowas in objektorientierter Programmierung nicht. Der Folgezeiger ist kein logischer Teil deines Objekts, sondern des Listenknotens, der es beinhaltet. Das heißt, statt

C++:
struct foo {
  int content;
  foo *next;
};


schreibst du

C++:
struct foo {
  int content;
};

struct list_node {
  foo value;
  list_node *next;
};

// und dann in ähnlicher Weise
struct tree_node {
  foo value;
  tree_node *left, *right;
};


Die Idee der objektorientierten Programmierung ist ja, unterschiedliche Funktionalitäten zu entkoppeln. Das heißt, was für eine Liste gebraucht wird, geht in eine Listenklasse, nicht in ihren Inhalt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
30.12.2007, 00:00 Uhr
~Popp
Gast


Guten Abend,

genau das gleiche hab ich mir eben auch gedacht, aber es gibt eben anscheinend Old Fashiend Programmierer die das immer noch verwenden, und den wahren Fortschritt von Klassen immer noch nicht verstanden haben.

Habe neulichst irgendwo im internet diese grausige klasse gefunden:

C++:
class Word
    { private:
         static Word* ROOT; //Klassenvariablen
      char* wort;
      int z;             //Wortzähler
      Word* nachfolger;  //Folgezeiger
      public:
      void print(){cout<<endl<< wort<<'\t'<<z;} //Objekt ausgeben
      void neu_satz(char*);                     //Neu anlegen
       void liste();
      void suchen(char*);                       //ist Wort vorhanden
      int laden(char*);                         //Datei laden
      int speichern(char*);
      void del();                               //Speicher freigeben
    };  //ende Klasse Word

//----------------------------  loescht die Liste  ----------------------------
void Word::del()                     //loescht die Liste
{Word*h;
for (Word*i=ROOT;i;i=h)    {delete [] i->wort;
                            h=i->nachfolger;
                            delete i;
                           }
ROOT=0;
}



da wurde mir echt angst und bange als ich das gelesen habe und dieser programmierer hat angeblich schon über 10 jahre erfahrung.

ich hab die klasse mal umgeschrieben mit weniger funktionen und identischer funktion ohne diesen mischmasch aus c und c++.


C++:
class CWords
{
private:
    typedef std::map<std::string, size_t> TWordList;
    TWordList m_List;
    // Non-copyable class (copy-constructor and assignment-operator)
    CWords(const CWords&);
    const CWords& operator = (const CWords&);
public:
    CWords(void) :
        m_List()
    {
    }
    virtual ~CWords(void)
    {
        m_List.clear();
    }
    // Generate a word list from a text file
    bool LoadFromFile(const std::string& a_FileName) throw();
    // Display the list on standard output
    void DisplayList(const size_t& a_PageSize = 0) throw();
    // Export the word list to a text file (CSV with TAB)
    bool SaveToFile(const std::string& a_FileName) throw();
};



und genau dann ist mir die frage gekommen ob man noch oft folgezeiger braucht, also ich brauche diese nicht, es ist so sogar noch kleiner und kompakter.

was sagt ihr dazu wenn ihr diese klasse schon mal seht?


Bearbeitung von 0xdeadbeef:

Header und #include des schlechten Beispiels auf Anfrage entfernt.


Dieser Post wurde am 30.12.2007 um 12:14 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
30.12.2007, 00:29 Uhr
0xdeadbeef
Gott
(Operator)


10 Jahre Erfahrung? Aber nicht mit C++. Das ist ja widerwärtig.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
30.12.2007, 11:11 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


da kann ich mich 0xdeadbeef nur anschließen, schon rein das include mit backslashes und vollständigen pfad ist schon widerwärtig. Jeder vernünftige Compiler akzeptiert slashes, weil backslash das escape-zeichen ist ...

Mal davon abgesehen das da ne Menge const's fehlen, dem ganzen die nötige korrekte OOP-Struktur fehlt, und wohl irgendwo in nem header ein using namespace std; stehen muss, sonst würde das mit dem cout in dem print() da oben nicht kompilieren

Von der Klasse kann auch nur eine einzige Wurzel existieren, durch das static ROOT ...

Von 10 Jahren C++ Erfahrung kann da nicht die Rede sein ...

Zu deiner Frage:
--------------------
die std::map könnte z.b intern als verkettete Liste aufgebaut sein, muss aber nicht. Deine Klasse so schaut schon nicht SO schlecht aus, auch wenn wohl Funktionen wie "add" und "del" nun fehlen, aber denk mal das war nur ein beispiel von dir.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
30.12.2007, 11:34 Uhr
0xdeadbeef
Gott
(Operator)


Vor allem stört mich die Verwendung von char* als String-Typ. Nicht mal const hat der das gemacht.

std::map kann übrigens nicht als verkettete Liste implementiert werden, der Standard garantiert logarithmische Laufzeitkomplexität für die meisten Operationen darauf. Typischerweise ist std::map intern ein Baum. (In der GNU-libstdc++ z.B. ein RB-Baum)
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
30.12.2007, 11:41 Uhr
~Popp
Gast


Guten Morgen,

genau das gleiche hab ich auch erst gedacht als ich das ganze gesehen habe, vor allem ist es nicht nur schlecht programmiert sondern des weiteren ist es total unübersichtlich.

Wie man in jedem guten Buch lesen kann und auch im Internet soll eine Klasse ja wiederverwendbar sein und auch auf das wesentlichste reduziert.

stimmt das eigentlich das man lieber mal eine klasse mehr machen sollte als eine zu wenig?

und noch eine frage ist mir da gekommen, ich kann ja objekte auch in vektoren packen also z. B.


C++:
std::vector<meineklasse> klasseinvector;


wenn ich das so mache hab ich ja auch zugriff auf alle memberfunktionen der klasse aus dem Vektor raus.

denn das wäre ja ne weitere möglichkeit die obere aufgabe zu lösen.


C++:
class wort
{
    private:
    std::string wort;
    unsigned int zaehler;
    public:
    wort()
    {
    }
    wort(const std::string& word)
    {
        wort = word;
        zaehler = 1;
    }
    ~wort()
    {
    }
    void set_wort(const std::string& word)
    {
        wort = word;
    }
    void vergleich(const std::string& vergleich)
    {
        if (vergleich == wort)
        {
            zaehler++;
        }

    }
    std::string get_word()
    {
        return wort;
    }
    unsigned int get_zaehler()
    {
        return zaehler;
    }
};



wenn ich das jetzt in meine klasse halt einfügen würde:


C++:
class CWords
{
private:
    typedef std::vector<wort> TWordList;
    TWordList m_List;
    // Non-copyable class (copy-constructor and assignment-operator)
    CWords(const CWords&);
    const CWords& operator = (const CWords&);
public:
    CWords(void) :
        m_List()
    {
    }
    virtual ~CWords(void)
    {
        m_List.clear();
    }
    // Generate a word list from a text file
    bool LoadFromFile(const std::string& a_FileName) throw();
    // Display the list on standard output
    void DisplayList(const size_t& a_PageSize = 0) throw();
    // Export the word list to a text file (CSV with TAB)
    bool SaveToFile(const std::string& a_FileName) throw();
};



dann würde es ja im Endeffekt fast das gleiche machen, ein Array der klasse wort erstellen und ich könnte über die memberfunktionen zugreifen.


C++:
m_List.at(x).set_word("Test");


Ach ja könnte hier einer der moderatoren bitte das include und den gesamten header von dem schlechten beispiel entfernen? das wäre sehr nett von euch, danke.

Bearbeitung von 0xdeadbeef:

Fehlendes /cpp-Tag eingefügt


Dieser Post wurde am 30.12.2007 um 12:05 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: