Zugriff verweigert auf protected Element



  • pro_develop schrieb:

    aber ich möchte doch auf exec() in a zugreifen, wo doch auch der static pointer drin ist ?

    Simon2 schrieb:

    Diese Besonderheit von protected ist mir auch erst ziemlich spät aufgefallen: Man darf nur auf das "eigene a" zugreifen. Das ist aber über den statischen Zeiger ptr nicht mehr gewährleistet.

    hustbaer schrieb:

    Wenn du sicher weisst dass "ptr" ein "b" ist, dann kannst du den Fehler mit einem static_cast umgehen.

    void b::func(void)
    {
        static_cast<b*>(ptr)->exec();  // aber nur, wenn "ptr" wirklich auf ein "b"-Objekt zeigt.
    }
    


  • tut mir leid ... ich hab's noch nicht kappiert 😕

    wenn ich den ptr auf a mit dem this-zeiger auf b initialisiere, dann zeigt
    dieser doch auf das Basis-Objekt (Teil a) des b-Objekts ... dann sollte es doch möglich sein, eine Member-Funktion von a aufzurufen .... 😞



  • Du darfst nur direkt mit einem Objekt von B auf die protected-Teile von A zugreifen. Jedoch nicht mit einem Objekt von A oder Zeiger auf A.

    class Base
    {
        protected:
           int test;
    };
    
    class Derived : public Base
    {
        void func();
    };
    
    void Derived::func()
    {
       Base* ptr = new Base();
       cout << ptr->test; // Nicht erlaubt
       cout << test;      // Ist erlaubt, entspricht ja ( this->test )
    }
    

    Die abgeleitete Klasse hat keinen Sonderzugriff auf protected Elemente von Base. Sie darf nur über ein Objekt von sich selbst drauf zu greifen.

    Verstanden 😉 ?

    Lg freeG



  • Hab dir mal ein kleines Beispiel gemacht:

    class A
    {
        protected:
            int i;
    };
    
    class B : public A
    {
        public:
            void fkt()
            {
                A a_objekt;
    
                B b_objekt;
    
                A* ptr;
    
                /*
                    Fehler:
                        Innerhalb der "Klasse B" darfst du nur von einem "B-Objekt" aus
                        auf die protected-Teile von A zugreifen.
                        Wenn der Zeiger aber auf ein "A-Objekt" verweist,
                        ist es ein Zugriff von außerhalb, und das erlaubt protected nicht.
                */
                ptr = &a_objekt; // Dieses Objekt hat nichts mit der "Klasse B" zu tun...
                ptr->i; // ...und du befindest dich außerhalb von "Klasse A" --> Fehler
    
                /*
                    "b_objekt" beinhaltet einen "A-Teil".
                    ( Es wird ja der Konstruktor der "Klasse A" aufgerufen,
                     wenn du ein "B-Objekt erstellst. )
                */
                ptr = &b_objekt; // Es ist ein "B-Objekt"...
                ptr->i; // ...Du bist innerhalb der "Klasse B" --> Zugriff erlaubt
            }
    };
    
    int main()
    {
        return 0;
    }
    


  • Danke für eure Hilfe 🙂

    Danke fr33g, mit deiner Erklärung hab ich's jetzt kappiert 🙄

    ich hab auch noch einen anderen Test gemacht:

    a hugo;
    
        a *ptr = &hugo;
    
        ptr->exec();
    

    damit taucht genau das gleiche Problem auf ...

    Wow ... ich hätte nicht gedacht, dass der Zugriffsschutz so komplex ist ...
    damit kann man sich ja regelrecht aussperren 😃

    das bedeutet also, dass einzelne Objekte einer Klasse auch gegenseitig vor Zugriffen auf die zugehörigen private oder protected Member geschützt sind ...



  • pro_develop schrieb:

    das bedeutet also, dass einzelne Objekte einer Klasse auch gegenseitig vor Zugriffen auf die zugehörigen private oder protected Member geschützt sind ...

    Nein.

    class foo
    {
    public:
     void bar (foo& other)
     {
       other.n = 5; //geht
     }
    private:
     int n;
    };
    

    Die privaten Member von other können von einem anderen Objekt des gleichen Types verändert werden!

    So habe ich deine Aussage auf jeden Fall verstanden.



  • pro_develop schrieb:

    Wow ... ich hätte nicht gedacht, dass der Zugriffsschutz so komplex ist ...
    damit kann man sich ja regelrecht aussperren 😃

    Ohne diese "Komplexität" könnte man protected sofort aushebeln, der "Schutz" wäre nicht-existent:

    // base.cpp
    
    class base
    {
    protected:
        int m_i;
    };
    
    // schummler.cpp
    
    class schummel_helper : public base
    {
    public:
        static void set_m_i(base& b, new_i_value)
        {
            b.m_i = new_i_value; // wäre schlecht wenn das erlaubt wäre...
        }
    };
    
    void schummeln(base& b, int new_i_value)
    {
        // man könnte so b.m_i setzen, obwohl dies eine freie funktion ist, die vererbungsmässig so überhaupt gar nix mit "base" zu tun hat
        schummel_helper::set_m_i(b, new_i_value);
    }
    


  • hustbaer schrieb:

    Ohne diese "Komplexität" könnte man protected sofort aushebeln, der "Schutz" wäre nicht-existent

    Diese Sonderregel hat aber auch Nachteile, welche einen zu teilweise nicht sehr sauberen Workarounds zwingt.

    Siehe z.B. in einem älteren Thread von mir (gerade am Anfang).



  • @Nexus: ich denke besser so als anders rum.



  • Es schadet nie, etwas von mehreren Seiten zu betrachten 😉



  • Natürlich nicht.
    Manchmal bringt es aber auch nix, weil ein Fall gänzlich klar ist (und auch nach weiterer Betrachtung bleibt) 😉


Anmelden zum Antworten