statischen Klassenpointer als struct zugänglich für alle erbenden Module machen. Compiler error.



  • Hallo Leute,

    ich habe zwei Klassen. Test1 (Elternklasse) und Test2 (Kindklasse, erbt von Test1). Ziel ist es in Test1 ein statisches Struct als Member zu haben, das für alle Kinder zugänglich gemacht werden soll, die von Test1 erben.

    Ich bekomme nun entweder den Kompilerfehler, dass mindestens ein mehrfach definiertes Symbol gefunden wird. Das liegt wohl an der äußeren Deklaration von module (module_t Test1::module;) oder, wenn ich diese Zeile auskommentiere, den Kompilerfehler, für eine nicht aufgelöste externe Variable.

    Das liegt wohl an den gegenseitigen Includes. Wie löst man das Problem, sodass die Kompilerfehler verschwinden und alle Kindklassen einwandfrei auf die statische Variable zugreifen können? (Der Sinn ist hierbei, später einen Pointer auf alle im Heap angelegten Module zu haben).

    Ist es überhaupt sinnvoll bei nur einer statischen Variable, die klassenübergreifend zur Verfügung gestellt werden soll, zu vererben? Gehört die Variable überhaupt in den protected Bereich? Oder würde auch in den public Bereich von Test1 gehen? Was wäre genau der Unterschied, ist mir nicht ganz klar.

    Danke euch!

    Code:

    Test1.h:
    
    #pragma once
    
    #include <iostream>
    #include <vector>
    #include <string>
    
    class Test2;
    
    typedef struct
    {
        Test2* test2;
        Test2* test2_;
    }module_t;
    
    class Test1
    {
    public:
        Test1(void);
        virtual ~Test1(void);
    private:
    protected:
        static module_t module;
    };
    
    module_t Test1::module;
    
    Test1.cpp:
    
    #include "Test1.h"
    
    Test1::Test1(void) 
    {
    };
    
    Test1::~Test1(void) 
    {
    };
    
    Test2.h:
    
    #pragma once
    
    #include "Test1.h"
    
    class Test2 : public Test1
    {
    public:
        Test2(void);
        virtual ~Test2(void);
        void function(void);
    private:
    protected:
    };
    
    Test2.cpp:
    
    #include "Test2.h"
    
    Test2::Test2(void)
    {
    };
    
    Test2::~Test2(void)
    {
    };
    
    void Test2::function(void)
    {
    	module.test2 = NULL;
    }
    


  • @des1re10 sagte in statischen Klassenpointer als struct zugänglich für alle erbenden Module machen. Compiler error.:

    Ich bekomme nun entweder den Kompilerfehler, dass mindestens ein mehrfach definiertes Symbol gefunden wird.

    Test1.h wird sowohl von Test1.cpp als auch von Test2.h und damit in weiterer Folge von Test2.cpp inkludiert was dazu führt daß es in zwei Übersetzungseinheiten ein Objekt mit dem Namen Test1::module gibt. Definiere Test1::module in Test1.cpp.

    @des1re10 sagte in statischen Klassenpointer als struct zugänglich für alle erbenden Module machen. Compiler error.:

    Gehört die Variable überhaupt in den protected Bereich? Oder würde auch in den public Bereich von Test1 gehen? Was wäre genau der Unterschied, ist mir nicht ganz klar.

    access specifiers


    • Wozu void in Parameterlisten?
    • Wozu leere Konstruktoren und Destruktoren hinschreiben? Wenn Du einen virtuellen Destruktor brauchst reicht virtual ~foo() = default; (Bzw. virtual ~foo() = 0; wenn die Klasse sowieso abstrakt ist.)
    • NULL ist sowas von 90er.


  • Als Zusatz zu dem von @Swordfish geschriebenen - das Stichwort dafür lautet: One Definition Rule



  • Okay, danke euch! Jetzt funktionierts.

    Eine Frage noch. Wie überprüfe ich in C++ korrekt, ob ein Objekt, das auf dem Heap erzeugt wurde, überhaupt existiert? Bzw. ob der Speicher an der Adresse frei ist. Mit == NULL klappt das nicht wirklich.



  • Finde das nicht gut mit dem "statischen Klassenpointer". Wenn du nicht genau weisst, was du tust, ist das sicher die falsche Art vorzugehen. Die korrekte Art wäre in der Basisklasse erstmal nur eine/mehrere Methoden zu haben, welche die Basisklasse anweisen Operationen auszuführen, anstatt sich einen Pointer zu holen und alles "manuell" durchzuführen.

    Woher diese Methoden dann wiederum bestimmte Pointer bekommeb, wenn tatsächlich nötig, müsste man nochmal für den konkreten Anwendungsfall herausfinden. Eine Möglichkeit werden z.B. eine Managerklasse, die dem Konstruktur der Basisklasse übergeben wird, während der Manager wiederum fürs verwalten aller Instanzen zuständig ist oder eine Factory die sich auch gleich noch um Konstruktion und Zerstörung von allem kümmert.





  • @des1re10 sagte in statischen Klassenpointer als struct zugänglich für alle erbenden Module machen. Compiler error.:

    Eine Frage noch. Wie überprüfe ich in C++ korrekt, ob ein Objekt, das auf dem Heap erzeugt wurde, überhaupt existiert? Bzw. ob der Speicher an der Adresse frei ist. Mit == NULL klappt das nicht wirklich.

    Das geht nicht. Du musst schon selbst tracken, welche Objekte leben und welche nicht. Weil das schwierig ist, solltest du möglichst auf "new" und "delete" verzichten (und stattdessen std::make_unique oder std::make_shared verwenden). Und wie @Swordfish schon schrieb, NULL ist out. Nimm stattdessen "nullptr", das ist ein Nullpointer und nicht die Zahl 0, ist also im Gegensatz zu NULL typsicher, d.h. sowas wie NULL + 7 geht (wenn auch mit Warnung), während nullptr + 7 gar nicht erst kompiliert.





  • Wahrscheinlich war ich noch zu sehr von der cunt-Variablen aus dem Nachbarthread abgelenkt. Edit: Habe ich jetzt berichtigt.



  • @wob Eigentlich wollte ich Dich nur darauf hinweisen, warten bis Du Deinen Post editiert hast und dann meine Antwort löschen ^^


Log in to reply