Care este diferența dintre "public", "privat" și "protejată" moștenire în C++? Toate întrebările pe care mi le'am găsit pe ATÂT de a face cu cazuri specifice.
class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
class D : private A // 'private' is default for classes
{
// x is private
// y is private
// z is not accessible from D
};
NOTĂ IMPORTANTĂ: Clasele B, C și D conțin toate variabilele x, y și z. Este doar o problema de acces.
Despre utilizarea protejate și private moștenire ai putea citi aici.
Pentru a răspunde la această întrebare, am'd place să descrie membru's evaluatorilor în primul rând în propriile mele cuvinte. Dacă știi deja acest lucru, treceți la rubrica "next:".
Există trei evaluatorilor care am'm conștienți de "public", "protejată" și "privat".
Să:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
privateMember
.Prin "este conștient de", adica "recunoaște existența, și, astfel, să fie capabil de a accesa".
Același lucru se întâmplă cu public, private si protected moștenire. Las's ia în considerare o clasa de Bază și clasa de "Copil" care moștenește de la "Bază".
Limita de vizibilitate de moștenire va face codul nu a putut să văd că o clasă moștenește o altă clasă: conversii Implicite de derivate la baza câștigat't de lucru, și `static_cast de bază derivate câștigat't de lucru, fie.
Numai membri/prieteni de o clasă poate vedea privat de moștenire, și numai membri/prieteni și clasele derivate pot vedea protejate moștenire.
publice moștenire
butonul de clasă : public fereastra { };
protected moștenire
struct empty_pair_impl : protejat empty_class_1 { non_empty_class_2 doua; };
struct pereche : privat empty_pair_impl { non_empty_class_2 &a doua() { return this->în al doilea rând; }
empty_class_1 &primul() { return this; // notificare vom reveni acest lucru! } };
** privat moștenire
șablon
publice membru
class pair { publice: Prima; O a doua; };
class fereastra { publice: int getWidth() const; };
protected membru
class stiva { protejate: vector<element - > c; };
class fereastra { protejate: void registerClass(window_descriptor w); };
** privat membru
class fereastra { privat: int latime; };
Rețineți că C-stil aruncă intenționat permite turnarea cu o clasă derivată de la un protected sau private din clasa de bază într-o definite și în condiții de siguranță și să arunce în cealaltă direcție. Acest lucru ar trebui să fie evitate cu orice preț, pentru că se poate face codul depinde de detaliile de implementare - dar dacă este necesar, puteți face uz de această tehnică.
Are de-a face cu cât de publice ale clasei de bază sunt expuse la clasa derivată.
Ca litb subliniază, moștenire publică este tradițională moștenire care le'll vedea în cele mai multe limbaje de programare. Care este modelelor o "ESTE UN" relație. Privat moștenire, ceva AFAIK specific C++, este un "puse în APLICARE ÎN TERMENI DE" relație. Asta este vrei sa utilizare interfața publică în clasa derivată, dar don't doriți ca utilizatorul clasei derivate pentru a avea acces la interfață. Mulți susțin că, în acest caz, ar trebui să agregate clasa de bază, care este, în loc de a avea clasa de bază ca un privat de bază, face într-un membru al derivate, în scopul de a reutiliza clasa de baza's funcționalitate.
Aceste trei cuvinte-cheie sunt, de asemenea, utilizat într-un context complet diferit pentru a specifica vizibilitate modelul de moștenire.
Acest tabel adună toate combinațiile posibile ale componentei declarație și modelul de moștenire prezentarea rezultă acces la componentele când subclasa este complet definit.
Tabelul de mai sus este interpretat în felul următor (aruncăm o privire la primul rând):
dacă o componentă este declarate ca publice și clasa sa este moștenit ca publice rezultate acces este publice.
Un exemplu:
class Super {
public: int p;
private: int q;
protected: int r;
};
class Sub : private Super {};
class Subsub : public Sub {};
Rezultă de acces pentru variabilele "p", "q", " r " în clasă Subsub este niciuna.
un Alt exemplu:
class Super {
private: int x;
protected: int y;
public: int z;
};
class Sub : protected Super {};
Rezultă de acces pentru variabilele "y", " z "în clasă Sub este protected și pentru variabila" x " este niciuna.
Un exemplu mai detaliat:
class Super {
private:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
int main(void) {
Super object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Acum, vă permite să definiți o subclasă:
class Sub : Super { };
int main(void) {
Sub object;
object.put(100);
object.put(object.get());
cout << object.get() << endl;
return 0;
}
Cel definit de clasa de nume Sub care este o subclasă a clasei numit Super
sau că Sub
clasa este derivat din cel de Super clasa.
Anii Sub
clasa a introduce nici noi variabile, nici noi funcții. Asta înseamnă că orice obiect din Sub
clasa mosteneste toate trasaturile după "Super" clasa fiind de fapt o copie a unui "Super" clasă de obiecte?
Nu. Nu.
Dacă am compila codul de mai jos, vom obține nimic, dar erorile de compilare spunând că "pune" și "a lua" metode sunt inaccesibile. De ce?
Când vom omite specificatorul de vizibilitate, compilatorul presupune că am de gând să se aplice așa-numitul privat moștenire. Aceasta înseamnă că toate publice superclasa componentelor transforma in ** privat acces privat, superclasa componentelor câștigat't fi accesibile la toate. În consecință, înseamnă că nu ai voie să folosească din urmă în subclasă.
Avem de a informa compilatorul care vrem să o păstrăm utilizate anterior politica de acces.
class Sub : public Super { };
să nu fie induși în eroare: asta nu înseamnă că privat componente ale Super clasa (cum ar fi de stocare variabilă) se va transforma în cele publice într-un oarecum mod magic. Privat componente va rămâne ** privat, publice va rămâne publice**.
Obiecte din anii Sub
clasa poate face "aproape" de aceleași lucruri ca și frații lor mai mari, creat de Super clasa. "Aproape" pentru că faptul de a fi o subclasă înseamnă, de asemenea, că clasa a pierdut accesul la componente private de superclasa. Nu putem scrie o funcție de membru al Sub
din clasa care ar fi în măsură să manipuleze direct de stocare variabilă.
Aceasta este o restricție foarte serioasă. Există vreo soluție?
Da.
Cel de-al treilea nivel de acces se numește protected. Cuvinte cheie protejat înseamnă că componenta marcate cu se comportă ca un public atunci când sunt utilizate de către oricare dintre subclase și arată ca unul privat pentru restul lumii. -- Acest lucru este valabil doar pentru public moștenit clase (cum ar fi Super-clasă în exemplul nostru) --
class Super {
protected:
int storage;
public:
void put(int val) { storage = val; }
int get(void) { return storage; }
};
class Sub : public Super {
public:
void print(void) {cout << "storage = " << storage;}
};
int main(void) {
Sub object;
object.put(100);
object.put(object.get() + 1);
object.print();
return 0;
}
După cum puteți vedea în exemplul de cod avem o nouă funcționalitate pentru `Sub-clasă și nu un lucru important: se accesează de stocare variabilă din clasa Super.
Nu ar fi posibil dacă variabila a fost declarată ca fiind private. În principal funcție de domeniul de aplicare variabila rămâne ascuns, oricum deci, daca scrie ceva de genul:
object.storage = 0;
Compilatorul va informa că este o eroare: 'int Super::depozitare' este protejat
.
În sfârșit, ultimul program va produce următorul rezultat:
storage = 101
Member in base class : Private Protected Public
Moștenirea de tip : Obiect moștenit ca:
Private : Inaccessible Private Private
Protected : Inaccessible Protected Protected
Public : Inaccessible Protected Public
1) Moștenire Publice:
o. Privat membri din clasa de Baza nu sunt accesibile în clasa Derivată.
b. Protejate membrii din clasa de Bază rămâne protected în clasa Derivată.
c. Publice membrii din clasa de Bază rămân public în clasa Derivată.
Deci, alte clase pot folosi publice de membri din clasa de Baza prin Derivate din clasa object.
2) Protejate Moștenire:
o. Privat membri din clasa de Baza nu sunt accesibile în clasa Derivată.
b. Protejate membrii din clasa de Bază rămâne protected în clasa Derivată.
c. Publice de membri din clasa de Baza devin prea protejat membri ai clasei Derivate.
Deci, celelalte clase pot't folosi publice de membri din clasa de Baza prin clasa Derivată obiect; dar acestea sunt disponibile pentru subclasă de Derivate.
3) Privat Moștenire:
o. Privat membri din clasa de Baza nu sunt accesibile în clasa Derivată.
b. Protejate & publice de membri din clasa de Baza devin private membri ai clasei Derivate.
Deci, nici membrii din clasa de Bază pot fi accesate de către alte clase prin Derivate din clasa object ca ele sunt private în clasa Derivată. Deci, chiar subclasă de Derivate clasa poate't a le accesa.
Publice moștenire modele un E-O relație. Cu
class B {};
class D : public B {};
fiecare " D " is a B
.
Privat moștenire modele o ESTE IMPLEMENTAT FOLOSIND relația (sau orice altceva care's a numit). Cu
class B {};
class D : private B {};
un " D "nu este un "B", dar fiecare " D "foloseste" B " în punerea sa în aplicare. Moștenire privat pot fi întotdeauna eliminate prin utilizarea de izolare în loc:
class B {};
class D {
private:
B b_;
};
Acest "D", de asemenea, pot fi implementate folosind "B", în acest caz, folosind sale b_
. Izolarea este mai puțin strânsă între tipurile decât moștenire, astfel încât, în general, ar trebui să fie de preferat. Uneori, utilizarea de izolare în loc de moștenire privat nu este la fel de convenabil ca moștenire privat. De multe ori care's o scuză pentru a fi leneș.
Eu nu't cred că știe cineva ce "protejată" moștenire modele. Cel puțin nu am't văzut nicio explicație convingătoare încă.
Dacă ai moștenit public dintr-o altă clasă, toată lumea știe că sunt moștenirea și poate fi folosit polymorphically de oricine printr-o clasa de baza pointer.
Dacă ai moștenit protectedly numai clasele de copii va fi capabil să se folosească de tine polymorphically.
Dacă ai moștenit privat numai tu va fi capabil să execute clasa părinte metode.
Care de fapt simbolizează cunoașterea restul de clase au despre relația ta cu părinții tăi de clasă
Date protejate membrii pot fi accesate de orice clase care moștenesc de la clasa ta. Date Private membri, cu toate acestea, nu se poate. Las's spun, avem următoarele:
class MyClass {
private:
int myPrivateMember; // lol
protected:
int myProtectedMember;
};
Din cadrul extensie la această clasă, făcând referire la asta.myPrivateMember va't de lucru. Cu toate acestea, acest lucru.myProtectedMemberva. Valoarea este încă încapsulate, deci, dacă avem o instanțiere din această clasă numit
myObj", apoi " myObj.myProtectedMember va't de lucru, astfel încât acesta este similar în funcție de la un privat datele membru.
Accessors | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public | y | y | y
—————————————+————————————+———————————————+———————
protected | y | y | n
—————————————+————————————+———————————————+———————
private | | |
or | y | n | n
no accessor | | |
y: accessible
n: not accessible
Bazat pe acest exemplu pentru java... cred ca un pic de masă în valoare de o mie de cuvinte :)
Rezumat:
Când moștenirea, puteți (în unele limbi) schimbarea tipului de protecție a datelor membru în anumită direcție, de exemplu, protejate de public.
Membrii private din clasa de bază pot fi accesate doar de membrii din clasa de bază .
Membrii publice de o clasa de baza pot fi accesate de membrii din clasa de bază, membrii consiliului său de clasă derivată precum și membrii care nu se încadrează în clasa de bază și clasa derivată.
Protejate membrii din clasa de bază pot fi accesate de membrii din clasa de bază precum și membrilor clasei derivate.
** privat: baza
protected: bază + derivate
publice: bază + obținute + orice alt membru
Am găsit un răspuns simplu și așa a crezut de a posta pentru viitor prea.
Sale de link-uri http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
class Base
{
public:
int m_nPublic; // can be accessed by anybody
private:
int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
class Derived: public Base
{
public:
Derived()
{
// Derived's access to Base members is not influenced by the type of inheritance used,
// so the following is always true:
m_nPublic = 1; // allowed: can access public base members from derived class
m_nPrivate = 2; // not allowed: can not access private base members from derived class
m_nProtected = 3; // allowed: can access protected base members from derived class
}
};
int main()
{
Base cBase;
cBase.m_nPublic = 1; // allowed: can access public members from outside class
cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}
L's, în esență, accesul protecția publicului și protejate ale clasei de bază în clasa derivată. Cu moștenire publice, clasa derivată poate vedea publice protejate și membrii de bază. Cu privat moștenire, se poate't. Cu protejate, clasa derivată și eventualele clase derivate din faptul că le pot vedea.