Czym są access specifiiers? Czy powinienem dziedziczyć z prywatnym, chronionym czy publicznym?

Jestem zdezorientowany co do znaczenia modyfikatorów dostępu w odniesieniu do dziedziczenia. Jaka jest różnica między dziedziczeniem obejmującym private, protected i public słowa kluczowe?

Author: Destructor, 2011-03-27

2 answers

Co to są access Specifiiers?

Istnieje 3 access specifiers dla klasy / struct / Union w C++. Te specyfikatory dostępu definiują, w jaki sposób można uzyskać dostęp do członków klasy. Oczywiście, każdy członek klasy jest dostępny w tej klasie (wewnątrz dowolnej funkcji członka tej samej klasy). W zależności od typu dostępu, są to:]}

Public - członkowie zadeklarowani jako Public są dostępni spoza klasy poprzez obiekt klasy.

Protected - członkowie zadeklarowani jako Protected są dostępni spoza klasy , ale tylko w klasie pochodzącej z niej.

Private - członkowie są dostępni tylko z poziomu klasy. Dostęp z zewnątrz nie jest dozwolony.

Przykład Kodu Źródłowego:

class MyClass
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

int main()
{
    MyClass obj;
    obj.a = 10;     //Allowed
    obj.b = 20;     //Not Allowed, gives compiler error
    obj.c = 30;     //Not Allowed, gives compiler error
}

Inheritance and Access Specifiiers

Dziedziczenie w C++ może być jednym z następujących typów:]}
  • Private Dziedziczenie
  • Public dziedziczenie
  • Protected dziedziczenie
Oto zasady dostępu członków w odniesieniu do każdego z nich:]}

pierwsza i najważniejsza reguła Private Członkowie klasy nigdy nie są dostępni skądkolwiek poza członkami tej samej klasy.

Dziedziczenie Publiczne:

Wszyscy Public Członkowie klasy bazowej stają się Public członkami Klasa pochodna &
Wszyscy Protected Członkowie klasy bazowej stają się Protected członkami klasy pochodnej.

Tzn. brak zmian w dostępie członków. Zasady dostępu, które omówiliśmy wcześniej, są następnie stosowane do tych członków.

Przykład Kodu:

Class Base
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

class Derived:public Base
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Allowed
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error

}

Prywatne Dziedzictwo:

Wszyscy Public Członkowie klasy bazowej stają się Private członkami klasy pochodnej &
Wszyscy Protected Członkowie klasy bazowej stają się Private członkami Klasa Pochodna.

Przykład kodu:

Class Base
{
    public:
      int a;
    protected:
      int b;
    private:
      int c;
};

class Derived:private Base   //Not mentioning private is OK because for classes it  defaults to private 
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

class Derived2:public Derived
{
    void doSomethingMore()
    {
        a = 10;  //Not Allowed, Compiler Error, a is private member of Derived now
        b = 20;  //Not Allowed, Compiler Error, b is private member of Derived now
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Not Allowed, Compiler Error
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error

}

Spadek Chroniony:

Wszyscy Public Członkowie klasy bazowej stają się Protected członkami klasy pochodnej &
Wszyscy Protected Członkowie klasy bazowej stają się Protected członkami klasy pochodnej.

Przykład Kodu:

Class Base
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

class Derived:protected Base  
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

class Derived2:public Derived
{
    void doSomethingMore()
    {
        a = 10;  //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2
        b = 20;  //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Not Allowed, Compiler Error
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error
}

Pamiętaj, że te same zasady dostępu mają zastosowanie do klas i członków w hierarchii dziedziczenia.


Ważne punkty do Uwaga:

- Access Specification is per-Class not per-Object

Zauważ, że access specification C++ działa na podstawie klasy, a nie na podstawie obiektu.
Dobrym tego przykładem jest to, że w konstruktorze kopiującym lub funkcji operatora kopiowania można uzyskać dostęp do wszystkich członków przekazywanego obiektu.

- Klasa pochodna może uzyskać dostęp tylko do członków własnej klasy bazowej

Rozważmy następujący przykład kodu:

class Myclass
{ 
    protected: 
       int x; 
}; 

class derived : public Myclass
{
    public: 
        void f( Myclass& obj ) 
        { 
            obj.x = 5; 
        } 
};

int main()
{
    return 0;
}

Daje błąd kompilacji:

Prog.w tym celu należy wykonać następujące czynności:]}

Ponieważ klasa pochodna może mieć dostęp tylko do członków swojej własna klasa bazowa. Zauważ, że obiekt obj przekazywany tutaj nie jest w żaden sposób powiązany z funkcją klasy derived, w której jest dostępny, jest zupełnie innym obiektem i dlatego derived funkcja member nie może dostęp do jego członków.


Co to jest friend? Jak friend wpływa na reguły specyfikacji dostępu?

Możesz zadeklarować funkcję lub klasę jako friend innej klasy. Gdy to zrobisz, reguły specyfikacji dostępu nie mają zastosowania do klasy/funkcji ed friend. Klasa lub funkcja może uzyskać dostęp do wszystkich członków danej klasy.

więc czy friendprzerywa enkapsulację?

Nie, wręcz przeciwnie, wzmacniają Enkapsulacja!

friendstatek jest używany do wskazania celowe silne sprzężenie pomiędzy dwoma bytami.
Jeśli istnieje specjalna relacja między dwoma podmiotami, taka, że jeden potrzebuje dostępu do innych private lub protected członków, ale nie chcesz wszyscy aby uzyskać dostęp za pomocą identyfikatora dostępu public, należy użyć friendship.

 138
Author: Alok Save,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-29 08:30:41

Wyjaśnienie Scotta Meyersa w efektywnym C++ może pomóc zrozumieć, kiedy ich używać-dziedziczenie publiczne powinno modelować relację is-a, podczas gdy dziedziczenie prywatne powinno być używane dla "is-implemented-in-terms-of" - więc nie musisz trzymać się interfejsu klasy nadrzędnej, po prostu używasz ponownie implementacji.

 4
Author: Ivan Vergiliev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-17 20:37:04