2011-09-05 21 views
16

Tengo un programa donde necesito crear una clase base que se comparte entre un dll y algún código de aplicación. Luego tengo dos clases derivadas diferentes, una en el DLL en la aplicación principal. Cada uno de estos tiene algunas funciones miembro estáticas que operan en los datos en la clase nase. (Necesitan ser estáticos como se usan como indicadores de función en otro lugar). En su forma más simple, mi problema se muestra a continuación.¿Puedo acceder a un miembro protegido de clases base de una función estática en una clase derivada?

class Base { 
protected: 
    int var ; 
}; 

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

Mi compilador se queja de que no puedo acceder a los miembros protegidos de PBASE a pesar de lo derivado ha protegido el acceso a la base. ¿Hay alguna forma de evitar esto o estoy malinterpretando algo? Puedo hacer que las variables base sean públicas, pero esto sería malo ya que en mi instancia real, estas son un trozo de memoria asignada y los semáforos para protegerlo para multihilo.

¿Ayuda?

+1

posible duplicado de [Acceso a las variables protegidas de los padres] (http://stackoverflow.com/questions/4829518/accessing-parents-protected-variables). Esto no es específicamente sobre si la función es 'estática', sino que se debe a que el parámetro a través del cual se accede al miembro base no es del tipo' Derived'. –

+0

El argumento para la función estática debe ser de la clase base para cumplir con los requisitos de llamada del puntero de función. Tal vez podría evitar esto usando un molde dinámico –

+1

Si puede controlar que la función solo se llame con punteros a objetos 'Base' que son sub-objetos de clase base de objetos 'Derivados' que puede usar' static_cast' para convertir 'Base *' a 'Derived *' en el cuerpo de la función. De lo contrario, tendrías que ser un "amigo" de "Base" o podrías cambiar 'var' para que sea público. Si no puedes hacer nada de esto, entonces estás estancado. –

Respuesta

10

En general (independientemente de si la función es estática o no), una función de miembro de la clase derivada solo puede acceder a base protegida miembros de clase de objetos de su tipo. No puede acceder a los miembros protegidos de la base si el tipo estático no es el de la clase derivada (o una clase derivada de él). Por lo tanto:

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

Así que supongo que como mi función estática se usa para un puntero de función y el argumento debe ser la clase base, debería ser capaz de convertir dinámicamente a la clase derivada. –

+1

Si la clase base tiene al menos una función virtual, sí. (O puede cambiar la función para tomar 'Derived *', y dejar 'dynamic_cast' al cliente.) –

0

especificador de acceso se aplica al mango Derived clase (referencia/puntero/objeto) y no los métodos de Derived clase misma. Incluso si el método no fuera static, habría terminado con el mismo error. Porque no está accediendo al var con el controlador derivado. Demo.

La forma correcta es proporcionar un método setter:

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

Nota: Hay otra manera de salir, pero no estoy seguro si es elegante.

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

Desafortunadamente en mi clase real los datos en la clase base son en realidad algunos bloques de memoria y una carga de semáforos para acceso multihilo. Usar getters y setters para los semáforos y la masa de la memoria parece muy engorroso, ya que hay quizás 10-15 variables en la base. –

Cuestiones relacionadas