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?
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
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 &
WszyscyProtected
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 &
WszyscyProtected
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 &
WszyscyProtected
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
friend
przerywa enkapsulację?
Nie, wręcz przeciwnie, wzmacniają Enkapsulacja!
friend
statek 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ć friend
ship.
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.
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