Was ist hier falsch?



  • Hallo,

    ich hab folgendes Template geschrieben:

    template<class T>
    class CList
    {
    public:
        CList(const T &p_Data);
    private:
        struct node
        {
            T m_tData;
            node* m_pnNext;
        };
        node *m_pnList;
    
    };
    
    template<class T> CList<T>::CList(const T &p_Data)
    {
        m_pnList = new node;
        m_pnList->m_tData = p_Data;
        m_pnList->m_pnNext = NULL;
    }
    
    int main()
    {
        CList<int> test(1);
    
        return 0;
    }
    

    Wenn es dann ans Kompilieren geht bekomme ich diese Fehlermeldungen:
    "NULL' : nichtdeklarierter Bezeichner"
    "'int' kann nicht in 'struct DLIST::CList<int>::node *' konvertiert werden"

    Das versteh ich aber nicht. NULL ist ja eigentlich bekannt. Und ich seh nicht ganz wo hier ein int in node* konvertiert werden soll.
    Was mach ich falsch?



  • eigentlich ist NULL ganz richtig eingesetzt, insofwern versteh ich die fehlermeldung nicht ganz.

    in jedem fall solltest du den Templatenamen ändern, oder willst du mit der MFC in konflikt kommen? (nimm weder T noch C, die sind zuweit verbreitet...)



  • woher soll NULL den herkommen? ist doch kein schlüsselwort. also erstmal #include <cstdlib>



  • nimm 0 statt NULL



  • oder 0x00000000



  • Original erstellt von Korbinian:
    in jedem fall solltest du den Templatenamen ändern, oder willst du mit der MFC in konflikt kommen? (nimm weder T noch C, die sind zuweit verbreitet...)

    das versth ich nicht ganz... templateparameter sind ja ansich ähnlich wie funktionsparameter und die kann ich ja auch nennen wie ich will ohne das ich probleme krieg (naja jedenfalls solang ich mich an die konventionen für bezeichner halte).
    und das mit dem zu weit verbreitet... nur weil sehr viele leute i also schleifenvariable benutzen heisst das ja nicht das ich das nicht machen sollte nur weil es zu verbreitet ist?

    😕

    [ Dieser Beitrag wurde am 16.05.2003 um 18:15 Uhr von japro editiert. ]



  • Original erstellt von <1>:
    woher soll NULL den herkommen? ist doch kein schlüsselwort. also erstmal #include <cstdlib>

    Da NULL ansonsten immer geht, möchte ich wissen warum es hier nicht geht! Und da ich die cstdlib sogut wie nie benutze, kann es daran nicht liegen! Also woran hängts? (btw... MSVC6 🙂 )



  • es muss einfach irgendein header aus dem standard da sein sonst ist NULL einfach nicht definiert. algorithm oder so geht also auch, muss nicht unbedingt stdlib sein.



  • Original erstellt von japro:
    das versth ich nicht ganz... templateparameter sind ja ansich ähnlich wie funktionsparameter und die kann ich ja auch nennen wie ich will ohne das ich probleme krieg ...

    hoppla, ich glaub du hast mich missverstanden. ich wollte nicht, dass er für den Template-typ nen anderen buchstaben als T verwendet, sondern für den templatenamen, sprich statt "CList" etwa "MyList"



  • *pling* sorry 🙄



  • Ahja - Denkfehler, danke!
    Und wegen dem Templatenamen - ich hab das in nem eigenen Namespace, damit ist das kein Problem. 🙂



  • Original erstellt von Drakos:
    Und wegen dem Templatenamen - ich hab das in nem eigenen Namespace, damit ist das kein Problem. 🙂

    der compiler liefert keinen fehler, aber du kannst den leser deines source codes ganz schön verwirren - denn ich verstehe unter CList eigentlich die CList der MFC und so geht es quasi allen programmieren.



  • Original erstellt von Shade Of Mine:
    der compiler liefert keinen fehler, aber du kannst den leser deines source codes ganz schön verwirren

    ...nicht, wenn er nicht mit WinApi / MFC programmiert. Wenn er das ganze unter z.B. Unix schreibt wird sicher niemand CList mit der CList Klasse der MFC verwechseln. Schon gar nicht, wenn er auch noch einen eigenen Namespace aussen rum packt.

    - denn ich verstehe unter CList eigentlich die CList der MFC und so geht es quasi allen programmieren.

    ...allerdings nur, wenn man auch mal mit WinApi oder MFC programmiert hat. Ich z.B. würde "CList" nicht mit irgendwas bestimmtem assoziieren.

    Allerdings gibbet ja auch ein CList bei der GTK Bibliothek oder in ECMAScript...



  • Wenn ich die Klasse mal weitergeben sollte, gibt es sowieso noch eine Dokumentation dazu, so dass eigentlich alle Verwirrungen vermieden werden sollten.

    Ausserdem denk ich, ist es recht schwer zu vermeiden, dass sich Namen irgendwann mal mit denen anderer Bibliotheken überschneiden. Und CList aus der WinAPI kenn ich z.B. nicht weil ich damit nicht programmiere.



  • Original erstellt von Drakos:
    CList aus der WinAPI

    ...existiert nicht! totaler Schwachsinn! 😡 😡 😡



  • Ihr versteht nicht:

    nahezu jeder Programmierer hat schonmal die MFC verwendet.
    ein CList wird also quasi immer mit MFC assoziiert.

    angenommen ich lese folgenden code:

    ...
    using other::foo;
    using other::CList;
    using other::foo2;
    ...
    CList list;
    list.add(foobar);
    

    sofort denke ich an MFC. Ich schau in keiner Doku nach, denn CList ist für mich MFC.

    Warum fragt ihr euch vielleicht: weil das C vor dem namen ein Namespace ist. Ja, richtig, das ist ein namespace und keine ungarische Notation.
    C steht für MFC und nicht für class
    (analog siehe Borland mit T)

    C ist also ein namespace, und wenn ich irgendwo
    MFC::List
    lese, dann denke ich an MFC
    und MFC::List ist die heutige schreibweise für
    CList

    ich rede jetzt garnicht davon, dass man keine prefixe verwenden soll, sondern dass man namespaces beachten soll.

    oder schreibt von euch jemand

    namespace myspace
    {
    namespace std
    {
    int tolower(int);
    }
    }

    wenn dann irgendwo steht
    std::tolower
    ist dann zwar myspace::std::tolower gemeint, aber beim lesen des codes wird jeder hier an std::tolower der C++ Lib denken.

    wenn ihr jetzt sagt ihr schreibt nur unter Linux, dann bedenkt bitte, dass es auch Leute gibt die von Windows kommen und mal die MFC benutzt haben. oder denkt daran, dass ihr euren code vielleicht auch unter windows verfügbar machen wollt....

    also immer daran denken:
    CList steht für MFC::List und nicht für class List



  • Hmmm, Shade also soll ich wenn ich eine Klasse schreibe immer erst nachforschen ob nicht irgendwer denken könnte es handle sich um die Listenklasse von XY? Die Namensgebung ist doch jedem selbst überlassen. Wie sinnvoll/-los das ist mag ja mal dahin gestellt sein. Bei CSonstwas denke ich nicht automatisch an die MFC...



  • Original erstellt von MaSTaH:
    Bei CSonstwas denke ich nicht automatisch an die MFC...

    machen wir mal eine umfrage wer bei

    CList
    CString
    CWinApp
    CApplication
    CObject

    ich wette die meisten denken an MFC.

    Der Sinn ist doch, dass das C sagt: Hallo, ich komme aus dem namespace der MFC.
    Wenn du List schreibst, dann denkt niemand an die MFC

    das ist der unterschied.

    Ich will jetzt nichtmal über die Problematik von Prefixen reden, sondern nur darüber, dass C der namespace der MFC ist.

    TObject ist ja auch eine Klasse von Borland - das weiß man, weil T der namespace von Borland ist.
    std::Object wäre eine Klasse der C++ Standardlibrary, dazu muss man keine doku lesen um das zu wissen.

    das ist der Sinn der namespaces. dass was zusammengehört steht im gleichen namespace.

    Würdest du:
    namespace mastah
    {
    namespace std
    {
    class list {};
    }
    }

    schreiben?
    so dass dann im code irgendwo einmal std::list auftaucht?
    wer denkt denn dann daran dass es in wirklichkeit mastah::std::list ist?
    also ich sicherlich nicht.

    Und jetzt stell dir mal vor, jemand will die Klasse CList in einer MFC anwendung verwenden... WIE soll das funktionieren?? man wird sich 100.000 mal vertun.

    selbiges bei einem C++ programm mit mastah::std::list.
    irgendwo taucht ein using namespace mastah auf und schupss die wups kennt sich keiner mehr aus ob std::list jetzt mastah::std::list oder ::std::list ist...

    Wir haben heute namespaces - da brauchen wir sie nichtmehr zu simulieren...



  • Original erstellt von Shade Of Mine:
    **machen wir mal eine umfrage wer bei

    CList
    CString
    CWinApp
    CApplication
    CObject

    ich wette die meisten denken an MFC.
    **

    Shade, mein Junge. Da hast du ganz richtig geraten. Auch ich dachte sofort an MFC. Willste nen Keks? 🙂



  • Also ich würde mal behaupten, dass es klare Konventionen gibt was namespaces angeht. So hat ein Namensraum nichts mit dem Namen einer Klasse zu tun, denn sonst wär es kein Namensraum und darüberhinaus wäre dann die Verwendung von Namensräumen in ihrem Sinn schon etwas eingeschränkter.
    _Ich_ arbeite _nicht_ mit der MFC und habe deswegen auch das 'C' nicht damit assoziiert. Das 'C' steht für class und nicht für mfC (was ohnehin nicht sonderlich logisch ist). Und ich werde ganz bestimmt _nicht_ jegliche Bibliothek durchforsten um zu sehen welche Buchstaben auf irgendwas hinweisen.
    Wenn jemand Bibliotheken, Programme oder sonstwas von mir nutzt, wird er sich schon die Mühe machen müssen, die Dokumentation wenigstens mal kurz anzuschauen. Und darüber wird dann recht schnell ersichtlich sein, dass es sich hier nicht um die MFC handelt.

    Und ausserdem zeigt mein Codebeispiel am Anfang des Beitrags klar eine Neudeklaration plus -definition einer Klasse. Also wie um ales in der Welt kommt man dann darauf, dass es sich um eine Klasse der MFC handelt? Noch zumal ich geschrieben habe "ich hab folgendes Template geschrieben"??? 😕


Anmelden zum Antworten