Frage an die Profis: Zugriff auf CTypedPtrArray Objekt -> ausführen dessen Methode.



  • Hallo,

    Habe hier folgendes Problem:

    Meine Klasse CModell besteht aus Objekten der Klasse CElement (CElement ist abstrakt, es werden Objekte ihrer Unterklassen erstellt (Factory Pattern)). Die erstellten Elemente speichere ich in einem CTypedPtrArray:

    CTypedPtrArray <CPtrArray , Ce8Element*> ptrModell;
    

    Aufgebaut wird die Struktur so:

    ...
    CNode temp;   //CNode ist Unterklasse von CElement
    nAktIndex = m_ptrElement.Add ( &temp ); 
    m_nAnzElements++;
    (*m_ptrElement[nAktIndex]).setAttributes();
    ...
    

    Weiterhin habe ich in der Klasse CModell eine public Methode definiert welche mir den Zeiger auf die aufgebaute Datenstruktur zurückgibt:

    void CModell::getModell(CTypedPtrArray <CPtrArray , Ce8Element*> *ptrModell)
    {
    	(*ptrModell).Copy(m_ptrElement);
    }
    

    Ok, nun bin ich in der Klasse CAlgo. Habe ich im private Bereich eine Instanz von CModell erstellt (Und ein CTypedPtrArray<CPtrArray, Ce8Element*>):

    private:
    	Ce8Modell								m_Modell;
    	CTypedPtrArray<CPtrArray, Ce8Element*> m_ptrModell;
    

    Nun geh ich hin, in die cpp von CAlgo und das sieht so aus:

    Ce8Algo::Ce8Algo()
    {
    	init(); 	
    }
    
    Ce8Algo::~Ce8Algo()
    {
    }
    
    bool Ce8Algo::init()
    {
    	m_Modell.buildModell();  //baut die Datenstruktur auf
    	m_Modell.getModell( &m_ptrModell);  //Hier hole ich mir die Datenstruktur
    
             //Nun möchte ich die einzelnen Instanzen bzw. dessen Attribute anzeigen lassen
             //print() ist in der CElement Klasse virtuell und wird in CNode überschrieben
             //PROBLEM: Er crasht bei: (*m_ptrModell[ii]).print();
    	for(UINT ii = 0; ii < m_Modell.getAnzElements(); ii++)
    	{
    		(*m_ptrModell[ii]).print();
    	}
    
    	return true;
    }
    

    Wenn ich aber (*m_ptrModell[ii]).print(); im CModell.cpp irgendwo aufrufe, dann klappts! Auch der GET (m_Modell.getModell( &m_ptrModell);) funktioniert. Kann mir beim besten Willen nicht erklären wieso er hier in der CAlgo.cpp an dieser Stelle crasht.
    Weiss jemand was es sein könnte?



  • Es scheint daran zu liegen, dass die print methode in der Klasse CElement virtuell ist, und es soll ja nicht die des Elementes verwendet werden sondern die vom CNode.
    Sobald ich das virtual wegnehme, crasht er nicht mehr. Aber es wird halt die methode von CElement aufgerufen und nicht die benötigte von CNode. Weiss jemand Rat?



  • CNode temp;   //CNode ist Unterklasse von CElement 
    nAktIndex = m_ptrElement.Add ( &temp );
    

    hier fügst du ja einen zeiger auf eine lokale variable hinzu. die ist nach der funktion ungültig. vielleicht liegts daran? 🙄



  • Hallo,

    Es sieht schon komisch aus, aber wenn ich die Referenz wegnehme, dann kriege ich:

    error C2664: 'Add' : cannot convert parameter 1 from 'class Ce8Node_C' to 'class Ce8Element *'
    

    Interessant ist halt dass es innerhalb der Klasse CModell (CModell.cpp) auf genau diesselbe Art funktioniert (Achtung: m_ptrElement heisst jetzt m_ptrGraph):

    CNode temp;   //CNode ist Unterklasse von CElement  
    nAktIndex = m_ptrGraph.Add ( &temp );
    CTypedPtrArray <CPtrArray , Ce8Element*> tstModell;
    getGraph(&tstModell);
    (*tstModell[nAktIndex]).print();
    

    Und wenn ich das ganze in der CAlgo (CAlgo.cpp) mache indem ich erst das Modell referenziere gehts nicht mehr:

    bool Ce8Algo::init(Ce8Modell *ptrModell)
    {
    	m_Modell = ptrModell;
    	(*m_Modell).getGraph( &m_ptrGraph);
    
    	for(UINT ii = 0; ii < (*m_Modell).getAnzElements(); ii++)
    	{
    		(*m_ptrGraph[ii]).print();
    	}
    	return true;
    }
    


  • weil die Variable temp nur innerhalb der Funktion gültig ist und dir dessen Zeiger speicherst ist der Zeiger nach der Funktion ungültig. Mach mal zum Test statt

    CNode temp;   //CNode ist Unterklasse von CElement  
    nAktIndex = m_ptrElement.Add ( &temp );
    
    nAktIndex = m_ptrElement.Add ( new CNode() );
    

    Funktioniert es dann?



  • achso: wenn du referenzen nimmst, dann mach das & vor temp weg.



  • nAktIndex = m_ptrElement.Add ( new CNode() );
    

    Geht leider nicht, deswegen der Umweg über die temp Variable.

    Ce8Element *temp = new Ce8Node_C;
    nAktIndex = m_ptrGraph.Add ( temp );
    

    Nun klappts! 🙂
    Anfängerfehler 😡



  • aber beachte. du musst das element auch irgendwann wieder freigeben mit delete



  • for (int ii = 0; ii < m_ptrGraph.GetSize(); ii++) { delete m_ptrGraph[ii]; }
    m_ptrGraph.RemoveAll();
    

    👍 🙂


Anmelden zum Antworten