2013-06-06 9 views
9

Vorrei sapere perché il seguente codice non viene compilato:C++ di errore: funzione base è protetto

class base { 
protected: 
    typedef void (base::*function_type)() const; 
    void function_impl() const {} // error: ‘void base::function_impl() const’ is protected 
}; 

class derived: public base { 
public: 
    operator function_type() const { 
    return boolean_test() == true ? &base::function_impl : 0; // error: within this context 
    } 

protected: 
    virtual bool boolean_test() const = 0; 
    virtual ~derived() {} 
}; 

int main(int argc, char* argv[]) { 
} 

g++ uscita:

~/protected_test$ g++ src/protected_test.cpp 
src/protected_test.cpp: In member function ‘derived::operator base::function_type() const’: 
src/protected_test.cpp:4:8: error: ‘void base::function_impl() const’ is protected 
src/protected_test.cpp:10:44: error: within this context 

Questo codice è stato adattato da here e non vedo uno che si lamenta al forum di discussione. Inoltre, sto usando g ++ 4.7.2 e lo stesso codice compila e collega bene con egcs-2.91.66.

+0

O un compilatore è bacato, o l'altro è. : D – Wug

risposta

10

Le specifiche di accesso protetto indicano che il puntatore ai membri deve essere formato tramite il tipo derivato (ad esempio derived::...) o un tipo ereditato da esso. Non è possibile denominare function_impl direttamente tramite base.

Ciò significa che nel tuo caso devi fare come

operator function_type() const { 
    return boolean_test() == true ? &derived::function_impl : 0; 
} 

Si noti che anche se si utilizza &derived::function_impl espressione per ottenere l'indirizzo, il tipo del risultato è ancora void (base::*function_type)() const, dal momento che il nome function_impl in questo caso risolve la funzione della classe base.

Se è stato compilato in un compilatore specifico (o in una versione specifica di esso), significa semplicemente che il compilatore ha consentito all'errore di passare, il che probabilmente spiega il codice al collegamento.

+1

+1. Il paragrafo pertinente è 11.4/1 –

+1

Non sono d'accordo con il tipo di risultato - il comportamento che descrivi non è sicuro per il tipo (non sono sicuro che l'errore sia tuo o nello standard C++). Questo crea una scappatoia che consente alle funzioni membro 'Derivate' di chiamare indirettamente' o.function_impl() 'anche quando' dynamic_cast (o) ', che non dovrebbe essere legale. –

+0

Ok, sembra che l'esempio nello standard C++ sia rotto. –

Problemi correlati