tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
9
ZUGRIFFE
4901
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    HolgerX HolgerX ist offline Mitglied Silber
    Registriert seit
    Apr 2004
    Ort
    Braunschweig
    Beiträge
    95
    Hallo,
    ich will in VS C++ 6.0 nen Template anlegen!

    Leider gibt es nirgendwo die Funktion Neues Template

    Jetzt habe ich einfach eine neue Klasse angelegt und folgendes am Anfang der Headerdatei stehen:
    Code :
    1
    2
    
    template <class T> class CBildMatrix  
    {

    Ausserdem werden dort die Variablen und Funktionen deklariert.
    Die Implementierung habe ich dann wie gewohnt in die .cpp Datei geschrieben.
    Beim Versuch den ganzen Kram zu kompilieren bekam ich folgende Fehlermeldung:
    Code :
    1
    
    Fuer die Verwendung einer Vorlagenklasse ist eine Vorlagen-Argumentliste erforderlich

    In einem anderen Forum habe ich gelesen, dass auch die gesamte Implementierung in die .h Datei geschrieben werden muss.

    Das habe ich dann auch getan und die .cpp gelöscht.

    Aber wie kann ich nun in einer anderen Klasse mein Template nutzen?

    Den Code habe ich aus einem Buch übernommen, dort stand dann folgender Aufruf:
    Code :
    1
    
     CBildMatrix<int> m1 (256,256);
    Leider stand nirgendswo, wie ich das ausserhalb einer Main-Methode, z.B. in meiner Headerdatei der anderen Klasse als Membervariable aufrufen kann.

    Jedenfalls schmeisst mir mein Kompiler immer Fehlermeldungen raus.
     

  2. #2
    Registriert seit
    Oct 2003
    Beiträge
    1.706
    also wenn du das Template in anderen Klassen nutzen willst dürfte
    eine

    PHP-Code:
    #include <template.h>

    class Irgendwas{
          
    Template<intmember;
    }; 
    genügen um das Template als Membervariable zu nutzen.

    2.) Wie hast du deine Methoden im Template definiert?

    Eine Beispiel Methode sollte folgendes sein:

    PHP-Code:
    template<typename T> class Template{
       ...
      
    Tfunktion(TaTb){...}
       ...

    Wenn du das alles befolgst sollte es eigentlich keine Probleme geben..

    Gruß Redwing

    p.S. Vielleicht kannst du auch Posten wie dein Template implementiert ist?
     
    "I'm not deaf, I'm ignoring you"
    ----

  3. #3
    Registriert seit
    Jul 2003
    Ort
    Duisburg (NRW)
    Beiträge
    1.788
    Das habe ich dann auch getan und die .cpp gelöscht.
    Hm, Templates existieren in der Tat eigentlich nur in Headerdateien. Sie sind ja auch keine Klassen oder Funktionen, sondern nur Vorlagen für Klassen oder Funktionen.

    Was soll deine Templateklasse denn tun oder sein? Kannst du mal -- wie bereits angesprochen -- vorhandenen Code posten? Dann kann ich dir gerne helfen, das Ganze in die richtige Form zu bringen.

    PS: Ich liebe Templates!
     
    Chor: "Wir sind der Chor, und wir stimmen zu. Wir stimmen zu, wir stimmen zu, wir stimmen zu."

  4. #4
    HolgerX HolgerX ist offline Mitglied Silber
    Registriert seit
    Apr 2004
    Ort
    Braunschweig
    Beiträge
    95
    So, hier habe ich mal den ollen Quelltext rüberkopiert, den ich aus dem Buch habe:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    // BildMatrix.h: Schnittstelle für die Klasse CBildMatrix.
    //
    //////////////////////////////////////////////////////////////////////
     
    #if !defined(AFX_BILDMATRIX_H__5E39E9A8_FDCC_4AAD_A55F_2E6EB09209C2__INCLUDED_)
    #define AFX_BILDMATRIX_H__5E39E9A8_FDCC_4AAD_A55F_2E6EB09209C2__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
     
    template <class T> class CBildMatrix  
    {
        unsigned int m_iXsize, m_iYsize; // Größe der Matrix
        T ** m_Matrix;
    public:
        CBildMatrix();
        CBildMatrix(const CBildMatrix&);
        CBildMatrix(int, int);
        virtual ~CBildMatrix();
        T* operator[] (int);             // access to Vector
        void operator = (const CBildMatrix&); //assign Matrix
        void operator = (const T& v);    // assign v to each element
        const T* operator[] (int) const; // read only access
        operator T**() {return CBildMatrix); } //efficient access
        int GetSizeX() const {return m_iXsize; } 
        int GetSizeY() const {return m_iYsize; } 
     
    };
     
    #endif // !defined(AFX_BILDMATRIX_H__5E39E9A8_FDCC_4AAD_A55F_2E6EB09209C2__INCLUDED_)
     
    template <class T> CBildMatrix<T>::CBildMatrix(int x, int y)
    {
        m_iXsize = x;
        m_iYsize = y;
        T* array = new T[x*y];
        m_Matrix = new T*[y];
        for (int i = 0; i<y, ++i)
            m_Matrix[i] = & (array[i*x]); // fill in vector pointers
    }
     
    template <class T> T* CBildMatrix<T>::operator [](int i)
    {
        return matrix [i];
    }
     
    template <class T> const T* CBildMatrix<T>::operator [] (int i) const
    {
        return matrix[i];
    }

    Also 100%ig habe ich den Quelltext nicht übernommen, lediglich einige Bezeichnungen von Namen sind anders.
    Außerdem sind noch die #if #endif Teile von VS drin.

    Der Aufruf sollte dann folgendermaßen sein:
    Code :
    1
    
    CBildMatrix<int> m1(256,256);
    Wieso muss ich beim Nutzen von Templates eigentlich das #include mit in die Headerdatei der anderen Klasse (wo ich das Template nutzen will) schreiben, und nicht wie gewohnt in die .cpp Datei ?
    Kann ich die Membervariable in der anderen Klasse nur deklarieren, ohne ihr einen Wert zuzuweisen? - Wie kann ich ihr dann innerhalb der .cpp Klasse einen Wert zuweisen?
     

  5. #5
    Avatar von Endurion
    Endurion Endurion ist offline Mitglied Diamant
    Registriert seit
    Apr 2004
    Beiträge
    2.151
    Ist m1ein Member einer anderen Klasse?

    Dann musst du die Initialisierung in den Constructor eben dieser Klasse packen.
    Z.Bsp so:

    Header:
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    class COberMotz
    {
    ...
     
      COberMotz();
     
      CBuildMatrix<int> m1;

    Cpp:
    Code :
    1
    2
    3
    4
    
    COberMotz::COberMotz() :
      m1( 256, 256 )
    {
    }

    Damit wird der Constructor deiner Template-Klasse mit den beiden Parametern aufgerufen.
     

  6. #6
    HolgerX HolgerX ist offline Mitglied Silber
    Registriert seit
    Apr 2004
    Ort
    Braunschweig
    Beiträge
    95
    Das funktioniert sogar!
    Danke!

    Aber warum zum Geier müssen die Membervariablen so
    Code :
    1
    2
    3
    
    CPfurz::CPfurz() : m1(256,256)
    {
    }
    initialisiert werden? Und nicht einfach so:
    Code :
    1
    2
    3
    4
    
    CPfurz::CPfurz()
    {
       m1(256,256);
    }
     

  7. #7
    Registriert seit
    Jul 2003
    Ort
    Duisburg (NRW)
    Beiträge
    1.788
    Die erste Methode (mit Initialisierungsliste) ruft direkt den passenden Konstruktor auf, um dein Objekt zu initialisieren. Das ist sehr effektiv.

    Bei der zweiten Version steht innerhalb deines Konstruktors ein Konstruktoraufruf für ein Objekt, das bereits vor Eintritt in den Konstruktor erzeugt worden ist (nämlich m1). Da kannst du nicht im Nachhinein noch mal einen Konstruktor aufrufen.
     
    Chor: "Wir sind der Chor, und wir stimmen zu. Wir stimmen zu, wir stimmen zu, wir stimmen zu."

  8. #8
    Registriert seit
    Jan 2002
    Ort
    Bayern
    Beiträge
    1.390
    Ja genau richtig, allerdings hat das mit Templates relativ wenig zu tun, denn das was Kachelator hier sagt, trifft allgemein auf Aggregationen von Objekten zu. (Aggregation kommt von UML)

    Das ist eine Aggregation:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    class A
    {
    public:
      A();
    };
     
    class B
    {
    public:
     B();
     A myA;  // hier eine Aggregation
    }

    Wie Kachelator schon sagte, wird das Objekt (myA)schon erzeugt bevor der Konstruktor von B durchlaufen wird.
    Man kann das Ganze aber auch umgehen, in dem man einen Zeiger als Aggregation verwendet:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    class A
    {
    public:
      A();
      A(int);
    };
     
    class B
    {
    public:
     B();
     ~B();
     A *myA;  // hier eine Aggregation allerdings "nur" als Zeiger auf A
    }
     
    B::B()
    {
      myA = new A(5) // hier wird das Objekt erstellt
    }
     
    B::~B()
    {
      delete myA;
    }

    So was hier passiert, ist, daß nur ein Zeiger deklariert wird, und erst der Kunstruktor von B aufgerufen wird und darin, dann der Kunstruktor von A, weil dort mit "new" erst das Objekt erzeugt wird.
    Da dieses Objekt jetzt auf dem Heap-Speicher dynamisch erzeugt wird, muss man es natürlich auch wieder "selbst" löschen, sonst gibt es ein Speicherleck! Siehe Destruktor von B.

    So ich hoffe das war etwas verständlich.

    Gruß Homer
     
    we would change the world if god gave us the source code...
    and remember, science is nothing more than reverse engineering nature...

    Current projects:
    - LdrawConverter

  9. #9
    Bobbin Bobbin ist offline Grünschnabel
    Registriert seit
    Mar 2005
    Beiträge
    3
    Hallo,

    dazu benötige ich nochmal Hilfe: ich möchte ein Item anlegen mit einem Parameter eines gewünschten Typs. Dazu habe ich die Klasse Item und das template ItemValue. IM Item habe ich einen Pointer, auf den ich das entsprechende ItemValue legen will.

    Das Template (ItemValue.h) sieht so aus:
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    template <class C> class ItemValue  
    {
    public:
        ItemValue();
    //  virtual ~ItemValue();
        C value;
    };


    Mein Item (Item.h) sieht so aus:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #include "ItemValue.h"
    class Item {
    public:
        Item();
        void Get(int&);
        virtual ~Item();
    private:
        int id;
        ItemValue *value;
    };
    typedef Item* pItem;

    und die Item.cpp so:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    #include "Item.h"
     
    Item::Item() {}    //Constructor
    Item::~Item() {}   //Destructor
     
    void Item::Get(int& value)
    {
        int lvalue = 0; 
        this->value =  new ItemValue <int>;
     
        this->value->value = lvalue;
    }

    Das geht aber leider nicht - der Typ stimmt nicht überein. Wie bekomme ich denn die Definition so hin, dass ich auf dem Pointer die Struktur zu liegen habe?

    Gruß Bobbin.

    Der Code ist stark vereinfacht - bis auf die Probleme
     

  10. #10
    Avatar von Endurion
    Endurion Endurion ist offline Mitglied Diamant
    Registriert seit
    Apr 2004
    Beiträge
    2.151
    Es gibt leider für Templates keine "Basisklasse" wie deinen ItemValue-Pointer.
    Du müsstest dir da entweder ein Interface dazwischenschalten (frickelig) oder auf einen generell wandelbaren Typen gehen (oder sowas wie boost::any verwenden).

    Ich war dann faul, und hab mir für einen Settings-Manager alles als String gespeichert. Bei ints oder floats wird dann einfach umgewandelt. Erspart einem eine Menge Ärger.
     

Ähnliche Themen

  1. Template Klasse
    Von MaxivB im Forum PHP
    Antworten: 20
    Letzter Beitrag: 17.01.09, 18:59
  2. Prob mit template klasse!!
    Von Headymaster im Forum PHP
    Antworten: 3
    Letzter Beitrag: 21.10.06, 22:12
  3. Antworten: 6
    Letzter Beitrag: 08.06.06, 20:49
  4. template Klasse ableiten?
    Von Squeegee im Forum VisualStudio & MFC
    Antworten: 2
    Letzter Beitrag: 29.12.05, 17:37
  5. Klasse/Template
    Von Fluctuator im Forum PHP
    Antworten: 2
    Letzter Beitrag: 11.02.03, 18:38