2014-07-25 3 views
7
class A { 
public: 
    A() {auto tmp = &A::foo;} 
protected: 
    void foo() {} 
}; 

class B : public A { 
public: 
    B() {auto tmp = &A::foo;} 
}; 

Klasse A kompiliert kein Problem. Klasse B ergibt sich ein Übersetzungsfehler:Warum ist es unmöglich, einen Zeiger auf eine geschützte Methode der Basisklasse zu erhalten?

'A::foo' : cannot access protected member declared in class 'A'

Warum ist das, was ist der Grund? Gibt es eine Möglichkeit, dies zu umgehen (wenn ich diesen Zeiger für einen Rückruf benötige, std::function usw.)?

Antwort

2

Wenn Sie in der Lage sind, einen Zeiger auf A::foo zu nehmen, könnten Sie es verwenden foo auf einem Objekt vom Typ CA oder vom Typ von A abgeleitet aufzurufen:

class B : public A { 
public: 
    void xx(A a) { auto tmp = &A::foo; a.*tmp(); } // illegal 
} 

Stattdessen nehmen einen Zeiger auf B::foo; Das ist in Ordnung, weil Sie es nur für Objekte vom Typ B, Ihrer eigenen Klasse, verwenden können.

1

Vermutlich für die Sicherheit. Wenn Sie einen Zeiger auf dieses Mitglied bekommen und es an jemanden weitergeben könnten, ohne dass eine Alarmglocke ertönt, wäre das riskant.

Hier eine Abhilfe (andere können es besser wissen):

class A { 
public: 
    A() {auto tmp = &A::foo;} 
protected: 
    void foo() {} 
}; 

class B : public A { 
public: 
    B() {auto tmp = &B::foo;} 
}; 

EDIT - dachte, Sie könnten eine A :: foo müssen verwenden, aber Sie haben nicht einmal das brauchen. Arbeitet ohne. Siehe:

Access to method pointer to protected method?

+0

„* Vermutlich zur Sicherheit *“ - es gibt viele Möglichkeiten Zeiger auf ein Element zu jedermann geben – SomeWittyUsername

1

Sie es durch B zugreifen können, das heißt:

class B : public A { 
public: 
    B() {auto tmp = &B::foo;} 
}; 

Sie nicht &A::Foo von außen B zugreifen können, da es geschützt ist, aber man kann durch Erbe (seit Foo wird ein Mitglied von B durch Vererbung), dh durch Aufruf &B::Foo

4

Why is that, what's the rationale?

Im Allgemeinen kann eine abgeleitete Klasse nur geschützte Mitglieder derselben abgeleiteten Klasse zuzugreifen, nicht von der Basisklasse selbst oder beliebiger Klassen mit der gleichen Basisklasse. So kann B auf geschützte Mitglieder von A über B zugreifen, aber nicht direkt über A.

Is there a way to circumvent this?

Das geerbt Mitglied ist auch ein Mitglied der B, und kann als solche zugegriffen werden:

auto tmp = &B::foo; 
Verwandte Themen