2012-06-06 13 views
15

Me gustaría tener una clase base que tenga un campo constante (como un ID único asociado a la clase que no se puede modificar después del tiempo de compilación). Hasta ahora, la declaración static const estaría bien. Ahora, me gustaría heredar esta clase base y asegurarme de que los niños de esta clase tengan el mismo campo, pero con sus propios valores. ¿Cómo puedo hacer esto?¿Es posible declarar un valor constante estático virtual en una clase de C++?

Digamos, me gustaría tener una clase base llamada Base con un campo ID que mantiene el valor de int 0. Entonces, me gustaría tener las clases A, B y C, siendo todas ellas niños públicos de Base y me gustaría asegurarme de que estos niños también tengan los campos ID con los valores respectivos de 1, 2 y 3 (al 'asegurarse', me refiero a algo así como obtener un error de compilación si no lo hacen ' t tener una ID explícitamente declarada).

Si pudiera lograr construir este escenario, mi expectativa sería que pedir el campo de un puntero Base*ID, que debería obtener diferentes valores dependiendo de si el puntero se creó como new A(), new B() o new C().

Mi conjetura sería declarar ID como , que por supuesto no tiene sentido y da un error de compilación.

Pero entonces, ¿qué puedo hacer para lograr el resultado descrito? (Lo único que podría imaginar sería declarar ID como una función virtual que devuelve un número entero y luego codificar el valor en el cuerpo de la función, pero estoy buscando algo más elegante.)

Gracias en ¡avanzar!

+0

polimorfismo sólo funciona para las funciones miembro y no es válida para los miembros de datos. – Mahesh

+0

He escrito una alternativa basada en plantillas: http://stackoverflow.com/a/36797199/1529139 – 56ka

Respuesta

15

Un método static no puede ser virtual y ningún miembro de datos puede ser virtual.

Pero puede ocultar static campos en clases derivadas y utilizar un método virtual para devolverlos.

class A 
{ 
public: 
    static const int ID = 0; 
    virtual int getID() { return A::ID; } 
}; 
class B : A 
{ 
public: 
    static const int ID = 1; 
    virtual int getID() { return B::ID; } 
}; 

Alternativa:

class A 
{ 
public: 
    A(int id = 0) : ID(id) {} 
    const int ID; 
    getID() { return ID; } 
}; 
class B : public A 
{ 
public: 
    B() : A(1) {} 
}; 
+0

Sí, esta es la única solución que conozco hasta ahora. ¿Pero no hay forma de resolver esto de una manera más elegante/simple? O si este es el único camino a seguir, entonces mi pregunta es más bien: ¿cuál es el motivo por el cual la herencia virtual que funciona con funciones no funcionará con los miembros de datos? Entiendo por qué en realidad 'static virtual 'no tendría sentido, pero realmente no puedo entender por qué, digamos, un simple' virtual const int' campo no tendría sentido ... –

+0

@ SiskaÁdám porque el comportamiento polimórfico no es definido para los miembros de datos. Es la forma en que el lenguaje está diseñado. Y es algo bueno IMO. –

+0

@ SiskaÁdám Publiqué una alternativa, pero todavía encuentro la primera mejor. –

Cuestiones relacionadas