2010-11-04 13 views
6

ho finito di codifica (con qualche aiuto) qualcosa di simile ieri:Come e perché è possibile modificare il livello di accesso di un membro?

#include <iostream> 

using namespace std; 

class A 
{ 
    public: 
     virtual void foo(){cout << "A::foo\n";} 
}; 

class B : private A 
{ 
    private: 
     virtual void foo(){ cout << "B::foo\n";} 
     void DoSomething(SomeOtherClass& o){o.DoSomething(*static_cast<A*>(this));} 
}; 

Ho provato a cambiare il metodo di eredità:

class B : public A 
{ 
    private: 
     virtual void foo(){ cout << "B::foo\n";} 
}; 

int main() 
{ 
    A* a = new B; 
    a->foo(); 
} 

Questo funziona ancora. Mi aspettavo un errore in fase di compilazione. Per favore dimmi perché questo è possibile e quali sono i possibili usi? Conosco un utilizzo a causa del primo scenario: puoi esporre interfacce diverse per classi diverse.

EDIT:

Nel secondo caso, l'uscita è B::foo.

+0

Dove ti aspettavi l'errore?Sulla dichiarazione della funzione come privata? O sulla chiamata della funzione? –

+0

Sono incuriosito. Sperando in una risposta che spiegherebbe i possibili usi di questa funzionalità (?). Un utilizzo potrebbe essere quello di forzare il programmatore a creare un'istanza della classe B come puntatore alla classe base A per poter utilizzare la sua interfaccia. Ma perché sarebbe una buona cosa, non lo so. – manneorama

+0

@PigBen: mi aspettavo che l'errore nella definizione di 'pippo' in' B' nel secondo caso. – nakiya

risposta

1

Potrebbe non rispondere a tutte le vostre domande direttamente, tuttavia ho deciso di metterlo qui per riferimento futuro. Inoltre, si prega di prenderlo con un pizzico di sale in quanto si basa sulla mia comprensione degli eventi che sono accaduti nel mondo standard C++, piuttosto che i reali.

Leggi this. Non ho ARM con me, ma l'articolo fornisce i dettagli necessari.

Nota 115 in C++ 0x dice

115) le dichiarazioni di accesso sono deprecato; membro using-dichiarazioni (7.3.3) fornisce un mezzo migliore di facendo le stesse cose. Nelle precedenti versioni del linguaggio C++, le dichiarazioni di accesso a erano più limitate; essi sono stati generalizzati e resi equivalenti alle dichiarazioni d'uso nell'interesse di semplicità. I programmatori sono incoraggiati a utilizzare le dichiarazioni di utilizzo, anziché le nuove funzionalità delle dichiarazioni di accesso , nel nuovo codice.

In sintesi:

Penso che l'ARM vietato inizialmente:

Una dichiarazione di accesso non possono essere utilizzati per limitare l'accesso a un membro che è accessibili nella classe base, né può essere utilizzato per abilitare l'accesso a un membro non accessibile nella classe base .

Ma più tardi immagino quando lo standard evoluto this was eventually allowed

+0

"eventualmente consentito" bene, ora sono deprecati. questa risposta ha avuto una citazione migliore: http://stackoverflow.com/questions/2084801/c-using-declaration-scope-and-access-control –

3
using namespace std; 

class A 
{ 
    public: 
     virtual void foo(){cout << "A::foo\n";} 
}; 

class B : public A 
{ 
    private: 
     virtual void foo(){ cout << "B::foo\n";} 
}; 

int main() 
{ 
    A* a = new B; 
    a->foo(); 
} 

Questo funziona perché al momento della compilazione il compilatore può vedere solo che a è un puntatore alla classe base A e foo() è un metodo pubblico essere chiamato su a, che è perfettamente valido. L'associazione virtuale avviene dinamicamente in fase di esecuzione dopo la compilazione, questa associazione virtaul decide che la chiamata effettiva è B::foo() e non A::foo() che è la penalità delle prestazioni dell'utilizzo del virtualismo.

+0

È facile capire perché funzioni. Ma avrebbe avuto molto più senso se non fosse stato permesso di rendere foo() privato in B. Quindi penso che la domanda sia, qual è la logica alla base di tale decisione progettuale. –

+0

@kotlinski: esiste un motivo di design molto famoso chiamato pattern "metodo modello" che utilizza questa logica. Si prega di controllare quello –

+1

Non vedo la connessione tra questo e il modello di progettazione del metodo del modello. – nakiya

Problemi correlati