Problemm mit verketteter Liste



  • Kollyn schrieb:

    Naja das große L ist mir nicht aufgefallen,

    Ja, aber dieses große L macht den Unterschied aus 😉

    nur Warum akzeptiert er es als Default = 10, wenn ich schreiben COblist();???

    Weißt du, was Default-Parameter sind? Das Konstrukt CObList::CobList(int nBlockSize=10); drückt aus, daß der Ctor einen optionalen Parameter hat. Wenn du dort einen Wert übergibst, wird dieser übernommen, andernfalls setzt der Compiler automatisch den vorgegebenen Wert ein.

    Kann ich das dann verwenden, oder ist CList immer noch besser? Den ELEMENT ist ja von CObject...

    Ja, du kannst es verwenden, aber CList ist trotzdem besser, weil es typsicherer ist.

    (in eine CObList kannst du beliebige CObject's packen und mußt dann zur Laufzeit herausfinden, was für einen Datentyp du hast (bzw. wenn du es vorher weißt, mußt du es dem Compiler trotzdem explizit mitteilen), in eine CList<ELEMENT*> kommen nur Zeiger auf ELEMENT'e, also kannst du dir die Typ-Überprüfung ersparen)



  • Ja, aber dieses große L macht den Unterschied aus
    Zitat:
    nur Warum akzeptiert er es als Default = 10, wenn ich schreiben COblist();???

    Weißt du, was Default-Parameter sind? Das Konstrukt CObList::CobList(int nBlockSize=10); drückt aus, daß der Ctor einen optionalen Parameter hat. Wenn du dort einen Wert übergibst, wird dieser übernommen, andernfalls setzt der Compiler automatisch den vorgegebenen Wert ein.

    Ja nur er aktzebtiert COblist() auch mit kleinem L...

    Alsowenn ich jetzt C List nehme, und will jett mit getName (Funktion von ELEMENT) die Namen vergleiche... Wie mach ich das?

    p.s.: Ich weiß blöde Fragen, aber die letzte verkettete Liste ist 2- 3 Jahre her... 😃



  • Kollyn schrieb:

    Ja, aber dieses große L macht den Unterschied aus
    Zitat:
    nur Warum akzeptiert er es als Default = 10, wenn ich schreiben COblist();???

    Weißt du, was Default-Parameter sind? Das Konstrukt CObList::CobList(int nBlockSize=10); drückt aus, daß der Ctor einen optionalen Parameter hat. Wenn du dort einen Wert übergibst, wird dieser übernommen, andernfalls setzt der Compiler automatisch den vorgegebenen Wert ein.

    Ja nur er aktzebtiert COblist() auch mit kleinem L...

    Nein, macht er nicht - sonst wäre der obige Code ja durch den Compiler gekommen.

    (zur Erklärung: In C wird bei einer fehlenden Typ-Angabe 'int' angenommen. Das ist in C++ eigentlich verboten, aber anscheinend ist der Compiler davon ausgegangen, daß du mit COblist m_Oblist; eine (implizit) int-Variable namens COblist anlegen wolltest und hat sich demzufolge über das fehlende Semikolon dahinter (und die fehlenden Typangaben für die Variablen COblist und m_Oblist) beschwert.

    Alsowenn ich jetzt C List nehme, und will jett mit getName (Funktion von ELEMENT) die Namen vergleiche... Wie mach ich das?

    Ganz einfach:

    CList<ELEMENT*,ELEMENT*> m_Oblist;
    ...
    CString name = m_Oblist.GetHead()->getName();
    

    (die Member der CList (GetHead(), GetNext() etc.) geben jeweils ein Listenelement zurück, in deinem Fall also einen Zeiger auf ELEMENT - mit dem kannst du alles machen, was man mit Zeigern so anfangen kann)



  • Ok THX, was würd ich ohne dich nur machen...

    Ich denke jetzt werde ich erstmal weiter kommen...

    Hatte mich halt nur gewundert, warum ich den Pointer in der PtrList net direkt ansprechen konnte....

    Aber jetzt is es mir klar...

    Is halt schlecht wenn man fast 3 Jahre kein c++ mehr gemacht hat...



  • Kollyn schrieb:

    Ok THX, was würd ich ohne dich nur machen...

    Dich von Hand durch die MSDN durchgraben 😃 (oder auf jemand anderen warten, der deine Fragen beantwortet)



  • __POSITION *position;
    
    	position = Dialog->m_Elementlist.GetHeadPosition();
    	if(!Dialog->m_Elementlist.IsEmpty())
    	{ 
    	 while(position != Dialog->m_Elementlist.GetTailPosition())
    	 {
    	 Dialog->m_ELE = Dialog->m_Elementlist.GetAt(position);
    	//position  = Dialog->m_Elementlist.GetNext(position);
    	//position = position + (sizeof(position));
    	//position = Dialog->m_Elementlist.GetNext(Dialog->m_Elementlist.Find(Dialog->m_ELE));
    	Dialog->m_ELE  = Dialog->m_Elementlist.GetNext(position);
    	position = Dialog->m_Elementlist.Find(Dialog->m_ELE);
    	}
    	}
    

    Was mache ich falsch? der soll jett alle Durchgehen, angefangen beim 1. GetHead... bis zum Letzten ...

    Doch ich kriege die Position nicht erhöht!...

    hätte ich eventuell statt:

    CList<ELEMENT*,ELEMENT*> m_Elementlist;
    

    diese nehmen sollen?

    CList<ELEMENT*,ELEMENT> m_Elementlist;
    

    oder dies?

    CList<ELEMENT*,ELEMENT&> m_Elementlist;
    


  • *in der MSDN nachsieht* Eigentlich erhöht die Funktion GetNext() die angegebene Position - und als Abbruchbedingung eignet sich eher pos!=NULL:

    for(POSITON p=m_list.GetHeadPosition();p!=NULL;m_list.GetNextPosition(p))
    {
      m_ELE = m_list.GetAt(p);
      ...
    }
    

    das ist auch ein Grund, warum mir die STL lieber ist - die Iteratoren sehen irgendwie eleganter aus ;):

    for(list<ELEMENT*>::iterator p=m_list.begin();p!=m_list.end();++p)
    {
      m_ELE = *p;
      ...
    }
    

    PS: Die Deklaration CList<ELEMENT*,ELEMENT*> ist schon richtig und hat vermutlich nichts mit deinem Problem zu tun (und ich bezweifle, daß CList<ELEMENT*,ELEMENT> durch den Compiler kommen würde - keine passende Zuweisung möglich).


  • Administrator

    1. Bei Zeigern empfehle ich immer noch CTypedPtrList

    2. So könnte das z.b. Aussehen

    // Include nicht vergessen!
    #include "afxtempl.h"
    
    // Irgendwo die Deklaration
    CTypedPtrList<CPtrList, ELEMENT*> MyList;
    
    // Wir sagen nun du hast die Liste irgendwo gefüllt und willst nun alle abrufen:
    ELEMENT* pElement = NULL;
    POSITION pos = MyList.GetHeadPosition();
    
    while(pos != NULL)
    {
        pElement = MyList.GetNext(pos);
        // Und nun was auch immer du mit pElement anstellen willst!
    }
    

    Referenz:
    CTypedPtrList / MSDN

    Grüssli



  • Naja wusste nicht , das GetNext auch die Pos erhöht... Habe das aber zwischenzeitlich inner de MSDN ziemlich versteckt gefunden...

    Will jetzt Sortieren, aber irgendwie klappt das noch nciht ganz...

    void CXml_of_IDOCDlg::sortElement()
    {
    	m_pos = m_Elementlist.GetHeadPosition();
    	m_Elementlist.GetTailPosition();
    
    	for (;m_pos != m_Elementlist.GetTailPosition(); m_Elementlist.GetNext(m_pos))
    	{
    	m_pos2 = m_pos;
    	m_ELE = m_Elementlist.GetNext(m_pos2);
    	for(;m_pos2 !=NULL;m_Elementlist.GetNext(m_pos2))
    		{
    		if(m_Elementlist.GetAt(m_pos)->getName() >  m_Elementlist.GetAt(m_pos2)->getName())
    			{	
    			m_ELE = m_Elementlist.GetAt(m_pos2);
    			m_ELE2 = m_Elementlist.GetAt(m_pos);
    			m_Elementlist.SetAt(m_pos,m_ELE2);
    			m_Elementlist.SetAt(m_pos2,m_ELE);
    		}
    
    			/*if(m_Elementlist.GetAt(m_pos)->getName() == m_Elementlist.GetAt(m_pos2)->getName())
    			{
    			m_ELE = m_Elementlist.GetTail();
    			m_Elementlist.RemoveAt(m_pos2);
    			m_Elementlist.SetAt(m_pos2,m_ELE);
    			m_Elementlist.RemoveTail();
    
    			}*/
    
    		}
    
    	}
    
    }
    

    Also wenn der Name des Ersten größer ist, soll er die Tauschen, Die GetName gibt CString zurück...

    Aber das klappt nicht.

    Des weiteren sollte er wenn 2 gleiche da sin den einen ldurch das ende ersetzen, und das Ende löschen...

    Habt ihr Idee warum das nicht geht?



  • OK das erste habe ich gefunden, habe doppelt getauscht...


  • Administrator

    Sortierverfahren (Wiki)

    Mehr gebe ich dir nicht. Etwas musst du ja auch noch selber machen. Obwohl das nicht mehr so viel ist, da die einzelnen Sortierverfahren sehr gut erklärt sind.

    Grüssli



  • Hi,

    Naja das Sortierverfahren is nicht das Problem, da diesen Programm nur sporadisch laufen wird, und auch dann nicht performance kritisch reicht mir Bubblesort...

    den habe ich ja auch umgesetzt, nur leider einen winzigen Fehler gemacht.

    if(m_Elementlist.GetAt(m_pos)->getName() >  m_Elementlist.GetAt(m_pos2)->getName())
                {    
                m_ELE = m_Elementlist.GetAt(m_pos2);
                m_ELE2 = m_Elementlist.GetAt(m_pos);
                m_Elementlist.SetAt(m_pos,m_ELE2);
                m_Elementlist.SetAt(m_pos2,m_ELE);
    

    Wie du siehst speicher ich pos2 in ELE aber screibe auch an pos2 ELE..

    Also doppelt getauscht.

    m_ELE = m_Elementlist.GetAt(m_pos2);
                m_ELE2 = m_Elementlist.GetAt(m_pos);
                m_Elementlist.SetAt(m_pos2,m_ELE2);
                m_Elementlist.SetAt(m_pos,m_ELE);
    

    So pastt... :p

    Aber auf jeden Fall danke für eure Hilfe... komme jetzt mit den Listen in MFC klar, und is auf jeden FAll schneller und einfacher als selber die verketteten Listen zu schreiben...


Anmelden zum Antworten