Vector Template Klasse



  • Meine ersten Endeavour in C++, will eine FIFO Template Klasse mithilfe eines Vektors implementieren. Ich ändere jeweils immer das letzte Objekt in dem Vektor.

    #pragma once
    #include "stdafx.h"
    
    template <typename T>
    class FIFOListe
    {
    public:
    	FIFOListe(void)
    	{
    		m_FIFOListe = new std::vector<T>();
    	}
    
    	~FIFOListe(void)
    	{
    		delete m_FIFOListe;
    	}
    
    	void insert(const T &in)
    	{
    		m_FIFOListe->push_back(in);
    	}
    
    	T extract()
    	{
    		T temp = m_FIFOListe[m_FIFOListe->size()]; //<--- Fehler!
    		m_FIFOListe->pop_back();
    		return temp;
    	}
    
    private:
    	std::vector<T>* m_FIFOListe;
    };
    
    #include "stdafx.h"
    #include "FIFOListe.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	FIFOListe<int>* MeineListe = new FIFOListe<int>();
    	MeineListe->insert(10);
    	std::cout << MeineListe->extract();
    }
    
    Error	1	error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'int'
    

    Uhm ich kann mir vorstellen warum der Compiler auf den Fehler kommt, aber nicht wie ich ihn lösen könnte.

    Falls ihr auch noch andere Schönheitskorrekturen habt, bitte melden.
    Danke 😃



  • Patrickssj6 schrieb:

    Error	1	error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'int'
    
    T temp = (*m_FIFOListe)[m_FIFOListe->size()];
    

    Lass dir aber gesagt sein, dass man mit C++ so nicht entwickelt. Verwende kein new und verzichte auf Zeiger. --> Erzeuge Objekte für den automatischen Speicher (Stack). Und schau dir mal RAII an.



  • template <typename T>
    using FIFOListe = std::queue<T>;
    


  • Danke zunächst für die Antwort. Ja ich verzichte gerne auf Zeiger (komme aus der C# Ecke).

    Ich frage mich nur, wann wird dann

    std::vector<T> m_FIFOListe;
    

    initialisiert?

    In C# kann man ja die Liste irgendwo deklarieren und dann mit new initialisieren.

    EDIT: Hab den oberen Beitrag nicht gesehen. Ja, ich weiß das es so was diese Datenstruktur schon gibt, wollte nur mal mit Templates und Klasen üben.



  • Patrickssj6 schrieb:

    Ich frage mich nur, wann wird dann

    std::vector<T> m_FIFOListe;
    

    initialisiert?

    Im Konstruktor:

    FIFOListe(void)
        {
            m_FIFOListe = new std::vector<T>();
        }
    

    Er wird immer dann aufgerufen, wenn du eine Instanz dieser Klasse erstellst.

    Und lass das void in der Parameterliste weg. 😉



  • Ich meinte wenn man es nicht mit new initilisiert. 🙂

    #pragma once
    #include "stdafx.h"
    
    template <typename T>
    class FIFOListe
    {
    public:
    	FIFOListe()
    	{
    		´//m_FIFOListe = new std::vector<T>(); <--Geht ja nicht bzw überflüssig?
    	}
    
    	~FIFOListe()
    	{
    
    	}
    
    	void insert(const T &in)
    	{
    		m_FIFOListe.push_back(in);
    	}
    
    	T extract()
    	{
    		T temp = m_FIFOListe.front();
    		m_FIFOListe.erase(m_FIFOListe.begin());
    		return temp;
    	}
    
    private:
    	std::vector<T> m_FIFOListe;
    };
    


  • Patrickssj6 schrieb:

    Ich meinte wenn man es nicht mit new initilisiert.

    So:

    #include <vector>
    using namespace std;
    
    template <typename T>
    class FIFOListe
    {
    	private:
    		vector<T> m_FIFOListe;
    
    	public:
    		void insert(const T& in)
    		{
    			m_FIFOListe.push_back(in);
    		}
    
    		T extract()
    		{
    			T temp = m_FIFOListe[m_FIFOListe.size()-1];
    			m_FIFOListe.pop_back();
    			return temp;
    		}
    }; 
    
    int main()
    {
    	FIFOListe<int> fifo_liste;
    
    	fifo_liste.insert(1);
    	fifo_liste.insert(2);
    	fifo_liste.insert(3);
    
    	fifo_liste.extract();
    }
    

    Der vom Compiler generierte default constructor übernimmt die Initialisierung des Vectors für dich. 🙂



  • Alles klar, vielen Dank 😃



  • evtl.

    T extract() 
    { 
        T temp = m_FIFOListe.back(); 
        m_FIFOListe.pop_back(); 
        return temp; 
    }
    


  • pssst. das ist alles kein FIFO sondern LIFO...

    Gugelmoser schrieb:

    Und lass das void in der Parameterliste weg. 😉

    Das wäre das letzte, was ich daran noch bemängeln würde.
    Vorher kämen:

    • fehlende op= und Copy-Ctor (bei der Pointer-Version)
    • die Verwendung des unnützen Pointers selbst (wurde ja schon gesagt)
    • das compilerspezifische #pragma an Stelle von include-guards (*)
    • _tmain statt main (benutze passende Projekte für native C++-Anwendungen) (*)
    • die Portabilitätseinbußen durch den in solch kleinen Projekten unnötigen PCH (*)
    • Gugelmoser's using-Direktive vor einer Klassendefinition, die in einen Header gehört (#)

    Das void in der Parameterliste ist einzig und allein Geschmackssache, der Rest nicht.

    _______
    (*) Kann man in MSVC sicherlich machen. #pragma once und PCH können in größeren Projekten sogar die Buildzeit erheblich verbessern. Aber wer mit Templates rumprobiert ist noch am Anfang der Lernphase, und da gehts darum, sauberes C++ zu schreiben und keinen compilerspezifischen Hick-Hack. Compilerspezifika sind getrennt von der Sprache zu lernen, sonst muss man auf die harte Tour feststellen, dass man beim Umstieg irgendwann "GCC-C++" als nächste Sprache lernen muss, weil der GCC keine "Visual-C++" versteht...
    (#) Wer lernt, schaut ab. Und wer die Feinheiten nicht kennt, übernimmt die using-direktive, die in dem 1-Source-Beispiel ok ist, in seinen Header. Und das ist nunmal ein No-Go => Vorsicht, was man Neulingen vormacht 😉



  • pumuckl schrieb:

    Gugelmoser's using-Direktive vor einer Klassendefinition, die in einen Header gehört. Wer lernt, schaut ab. Und wer die Feinheiten nicht kennt, übernimmt die using-direktive, die in dem 1-Source-Beispiel ok ist, in seinen Header. Und das ist nunmal ein No-Go => Vorsicht, was man Neulingen vormacht 😉

    Stimmt, in dem Moment habe ich nicht daran gedacht, dass der TE auf die Idee kommen könnte, es so in seiner Header zu übernehmen. Deinen restlichen Aufzählungspunkten stimme ich auch zu, bis auf das void in der Parameterliste :p.


Anmelden zum Antworten