2011-09-05 12 views
16

Ho un programma in cui ho bisogno di fare una classe base che è condivisa tra una DLL e qualche codice di applicazione. Quindi ho due diverse classi derivate, una in dll nell'applicazione principale. Ognuno di questi ha alcune funzioni membro statiche che operano sui dati nella classe nase. (Devono essere statici come sono usati come puntatori di funzioni altrove). Nella sua forma più semplice il mio problema è mostrato sotto.Posso accedere a membri di classi di base protette da una funzione statica in una classe derivata?

class Base { 
protected: 
    int var ; 
}; 

class Derived : public Base { 
    static bool Process(Base *pBase) { 
    pBase->var = 2; 
    return true; 
    } 
}; 

mio compilatore si lamenta che non posso accedere ai membri protetti di Pbase anche se derivato, ha protetto l'accesso alla Base. C'è un modo per aggirare questo o sto fraintendendo qualcosa? Riesco a rendere pubbliche le variabili di Base, ma questo sarebbe un problema, dato che in realtà sono un ammasso di memoria allocata e i semafori per proteggerlo per il multithreading.

Aiuto?

+1

possibile duplicato del [Accesso variabili protette del genitore] (http://stackoverflow.com/questions/4829518/accessing-parents-protected-variables). Questo non riguarda specificamente se la funzione è 'statica', ma perché il parametro attraverso il quale si accede al membro di base non è di tipo" Derivato ". –

+0

L'argomento della funzione statica deve essere della classe base per essere conforme ai requisiti di chiamata del puntatore della funzione. Forse potrei aggirare questo usando un cast dinamico –

+1

Se puoi controllare che la funzione sia chiamata solo con i puntatori agli oggetti 'Base' che sono sotto-oggetti di classe base degli oggetti' Derivati' che puoi usare 'static_cast' per convertire da 'Base *' a 'Derivato *' nel corpo della funzione. Altrimenti dovresti essere un 'amico' di' Base' o potresti cambiare 'var' come pubblico. Se non puoi fare nessuno di questi, allora sei bloccato. –

risposta

10

In generale (indipendentemente dal fatto che la funzione sia statica o meno), una funzione membro della classe derivata può accedere solo ai membri della classe protetta di oggetti del suo tipo. Non può accedere ai membri protetti della base se il tipo statico non è quello della classe derivata (o una classe derivata da essa). Quindi:

class Base { 
protected: 
    int var; 
} ; 

class Derived : public Base { 
    static void f1(Derived* pDerived) 
    { 
     pDerived->var = 2; // legal, access through Derived... 
    } 
    static bool Process(Base *pBase) 
    { 
     pBase->var = 2 ; // illegal, access not through Derived... 
    } 
} ; 
+0

Quindi suppongo che la mia funzione statica sia utilizzata per un puntatore a funzione e che l'argomento debba essere la classe base che dovrei essere in grado di eseguire il cast dinamico alla classe derivata. –

+1

Se la classe base ha almeno una funzione virtuale, sì. (Oppure puoi cambiare la funzione per prendere un 'Derived *', e lasciare il 'dynamic_cast' al client.) –

0

specificatore di accesso si applica al manico Derived di classe (di riferimento/puntatore/oggetto) e non i metodi di Derived classe stessa. Anche se il metodo non fosse static, avresti finito con lo stesso errore. Perché non si sta accedendo a var con l'handle derivato. Demo.

Il modo corretto è quello di fornire un metodo setter:

class Base { 
protected: 
    int var ; 
public: 
    void setVar(const int v) { var = v; } // <--- add this method 
}; 

Nota: V'è un altro modo, ma io non sono sicuro se è elegante.

(static_cast<Derived*>(pBase))->var = 2; 
+0

Sfortunatamente nella mia vera classe i dati nella classe base sono in realtà alcuni blocchi di memoria e un carico di semafori per accesso multi-thread. Usare getter e setter per i semafori e il grumo di memoria sembra molto complicato in quanto ci sono forse 10-15 variabili nella base. –

Problemi correlati