Posso accedere a classi di base protetta utenti da una funzione statica in una classe derivata?

StackOverflow https://stackoverflow.com/questions/7307200

Domanda

Ho un programma in cui ho bisogno di fare una classe di base che è condiviso tra una DLL e un po 'di codice dell'applicazione. Poi ho due differenti classi derivate, uno in una DLL nell'applicazione principale. Ognuno di questi hanno alcune funzioni membro statiche che operano sui dati nella classe nasi. (Hanno bisogno di essere statici come vengono utilizzati come puntatori a funzioni altrove). Nella sua forma più semplice il mio problema è mostrato di seguito.

class Base {
protected:
  int var ;
};

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

Il mio compilatore si lamenta che non posso accedere ai membri protetti della Pbase anche se derivato, ha protetto l'accesso alla Base. C'è un modo per aggirare questo o sto fraintendendo qualcosa? Posso fare le variabili di base pubblico, ma questo sarebbe un male come nel mio vero esempio questi sono un pezzo di memoria allocata ei semafori per proteggerlo per il multithreading.

Aiuto?

È stato utile?

Soluzione

In general (regardless of whether the function is static or not), a member function of the derived class can only access protected base class members of objects of its type. It cannot access protected members of the base if the static type is not that of the derived class (or a class derived from it). So:

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...
    }
} ;

Altri suggerimenti

Access specifier applies to the Derived class handle (reference/pointer/object) and not the methods of Derived class itself. Even if the method was not static, you would have ended up with the same error. Because you are not accessing var with the derived handle. Demo.

The correct way is to provide a setter method:

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

Note: There is one more way out, but I am not sure if it's elegant.

(static_cast<Derived*>(pBase))->var = 2;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top