2010-04-29 16 views
8

tengo estas clases de C++:Las variables estáticas en método estático en la clase base y la herencia

class Base 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base 
{ 

}; 

class B : public Base 
{ 

}; 

¿La variable estática x ser compartido entre A y B, o a cada uno de ellos tiene su propio x variable independiente (¿Qué es lo que quiero)?

+2

¿No es algo que podría verificar rápidamente con un compilador y algún código de prueba? –

+2

@ttmrichter: no si hay alguna sospecha de que pueda depender de la implementación. Y para cuando hayas comprobado que no es así, has encontrado la respuesta. –

+0

@ttmrichter Sospeché que la variable se compartiría, pero también quería ver si alguien tiene otra forma de resolver mi problema :) – Meh

Respuesta

14

Solo habrá una instancia de x en todo el programa. Una buena solución alternativa es utilizar el CRTP:

template <class Derived> 
class Base 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base<A> { }; 
class B : public Base<B> { }; 

Esto creará una diferente Base<T>, y por lo tanto una clara x, para cada clase que se deriva de ella.

También puede necesitar una base "Baser" para retener el polimorfismo, como señalan Neil y Akanksh.

+0

Bien, publicaste cuando estaba a punto de enviar :). – Akanksh

+2

Pero lo que no se obtiene es polimorfismo, si es necesario. –

+0

Gracias, olvidé que resolví un problema muy similar hace muchos años, también con CRTP :) – Meh

3

Solo habrá una, compartida por las tres clases. Si desea instancias separadas, deberá crear funciones separadas en las clases derivadas.

2

La primera. Las variables estáticas locales están vinculadas al método que las contiene, y method existe en una encarnación para todas las subclases (de hecho, para toda la aplicación, aunque el resto del programa no vea el método).

1

La variable se compartirá - es por función - en este caso la función a la que pertenece es Base::method(). Sin embargo, si class Base fuera una clase de plantilla, obtendría una instancia de la variable para cada instanciación (cada conjunto único de parámetros de plantilla reales) de la plantilla class Base - cada instanciación es una función nueva.

1

Si está haciendo que X sea estático, se compartirá entre todas las clases secundarias. No hay problemas con la función siendo estática.

3

Estoy bastante seguro de que será compartida entre A y B.

Si desea variables independientes se puede utilizar el "patrón de plantilla Curiosamente recurrente" como:

template<typename Derived> 
class Base 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base<A> 
{ 

}; 

class B : public Base<B> 
{ 

}; 

Por supuesto, si usted quiere polimorfismo, se tendría que definir una clase incluso "Baser" que se deriva de la base, como Base<A> es diferente de Base<B> como:

class Baser 
{ 
}; 

template<typename Derived> 
class Base : public Baser 
{ 
protected: 
    static int method() 
    { 
     static int x = 0; 
     return x++; 
    } 
}; 

class A : public Base<A> 
{}; 

class B : public Base<B> 
{}; 

Ahora A y B también pueden ser polimórficos.

Cuestiones relacionadas