È possibile accedere solo ai membri protected
dalla propria istanza della classe base ... non fornita come parametro. Si tratta davvero di incapsulamento OO. Senza questa restrizione, l'oggetto in costruzione potrebbe invalidare gli invarianti del parametro baseTest&
.
In altre parole, il vostro SubTest
può decidere su un ricorso per un membro protected
che è in conflitto con l'uso fatto dello stesso elemento da un'altra classe -derived BaseTest
(diciamo SubTest2 : BaseTest
). Se il tuo codice SubTest
è stato autorizzato a trafficare con i dati degli altri oggetti, potrebbe invalidare gli invarianti in un oggetto SubTest2
o ottenere alcuni valori che erano - nell'incapsulamento previsto - destinati solo a essere esposti a SubTest2
e (facoltativamente - vedi sotto) Derivati SubTest2
.
Followup question: Why is it, that in the added copy constructor I can access protected members of another instance?
SubTest(const SubTest& x); // can access x._protMember
SubTest(const BaseTest& x); // cannot access x._protMember
Le stesse intuizioni sopra spiegano perché questo è consentito: il costruttore di copia ottiene un SubTest&
piuttosto che un qualsiasi vecchio oggetto derivato da BaseTest
, e questo costruttore è chiaramente nel SubTest
astrazione. Si presume che il codificatore SubTest
abbia dimestichezza con il design/incapsulamento previsto SubTest
e che il costruttore di copie abbia accesso a bypass e imponga condizioni/invarianti di post sull'altro oggetto SubTest&
. (Stai copiando da un oggetto che potrebbe essere stato copiato dalla stessa funzione, quindi proteggerlo quando si trova sul lato "*this
" ma non sul parametro by-ref non è affatto una protezione, anche ignorando tutti i motivi validi che potresti desiderare/bisogno di quell'accesso).
E 'possibile che un oggetto -derived SubTest
verrà accidentalmente passato al costruttore di copia SubTest
("slicing"), ma anche per quello scenario la classe SubTest&
può controllare se l'oggetto ulteriormente-derivato si sarebbe potuto fare qualcosa di inaspettato con _protMember
- aggiunta di una dichiarazione private
using BaseTest::_protMember;
se si desidera "finalizzare" l'accesso a _protMember
e vietare a qualsiasi classe derivata di utilizzarlo.
fonte
2013-07-18 07:23:39
Grazie per la risposta. Potresti dare un'occhiata alla mia domanda successiva che ho aggiunto (con una funzione che _can_ accede ai membri protetti di un'altra istanza. –
@RonaldMcBean: Ho aggiunto alla mia risposta la risposta ("che può accedere ai membri protetti di un'altra istanza" - ma non un'istanza derivata da 'BaseTest'-but-not-'SubTest' - c'è il problema) –
Questa è un'ottima risposta: mi sono imbattuto in questo problema alcuni anni fa e mi ci è voluto molto tempo per elaborare * * perché ** il compilatore si è comportato in questo modo: mi sono reso conto che i progettisti di C++ hanno fatto un ottimo lavoro nel comprendere le sottigliezze di dove si trovano le responsabilità nell'orientamento agli oggetti. – TooTone