c++ - poo - ¿Hay alguna manera de evitar que un método sea anulado en subclases?
ejercicios de clases abstractas e interfaces en java (14)
A menos que haga que el método sea virtual, la clase hija no puede anularlo. Si desea evitar que las clases para niños lo llamen, hágalo en privado.
Por lo tanto, C ++ hace lo que quiere de forma predeterminada.
¿Alguien está al tanto de una característica o técnica de lenguaje en C ++ para evitar que una clase de niño use un método particular en la clase de padres?
class Base {
public:
bool someGuaranteedResult() { return true; }
};
class Child : public Base {
public:
bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};
Aunque no es virtual, esto todavía está permitido (al menos en el compilador de Metrowerks que estoy usando), todo lo que obtienes es una advertencia de tiempo de compilación sobre la ocultación de la función heredada X no virtual.
Los métodos de C ++ son privados y no se pueden sobrescribir por defecto.
- No puede anular un método privado
- No puede anular un método no
virtual
¿Quizás te estás refiriendo a la sobrecarga?
Si direcciona la clase secundaria como un tipo de su padre, entonces una función no virtual llamará a la versión de la clase padre.
es decir:
Parent* obj = new Child();
Un par de ideas:
- Haga su función privada.
- No hagas que tu función sea virtual. Sin embargo, esto no impide que la función quede sombreada por otra definición.
Aparte de eso, no conozco una función de idioma que bloqueará su función de tal manera que evite que se sobrecargue y aún pueda invocarse a través de un puntero / referencia a la clase secundaria.
¡Buena suerte!
una advertencia de tiempo de compilación sobre la ocultación de la función heredada no virtual X.
cambie la configuración del compilador para que sea un error en lugar de una advertencia.
Intentar evitar que alguien use el mismo nombre que su función en una subclase no es muy diferente a tratar de evitar que alguien use el mismo nombre de función global que ha declarado en una biblioteca vinculada.
Solo puede esperar que los usuarios que pretendan usar su código, y no los de otros, tengan cuidado con la forma en que hacen referencia a su código y que utilicen el tipo de puntero correcto o que utilicen un alcance totalmente calificado.
¡¡Supongo que lo que el compilador te advierte es que se está escondiendo !! ¿Está siendo anulado?
el compilador puede darle una advertencia, pero en tiempo de ejecución, se llamará al método de clase principal si el puntero es del tipo clase primaria, independientemente del tipo real del objeto al que apunta.
Esto es interesante. Intenta hacer un pequeño programa de prueba independiente para tu compilador.
(a) No creo que hacer que la función sea privada es la solución porque eso solo ocultará la función de la clase base de la clase derivada. La clase derivada siempre puede definir una nueva función con la misma firma. (b) Hacer que la función no sea virtual tampoco es una solución completa porque, si la clase derivada redefine la misma función, siempre se puede llamar a la función de clase derivada mediante el enlace de tiempo de compilación, es decir, obj.someFunction () donde obj es una instancia del clase derivada.
No creo que haya una manera de hacerlo. También me gustaría saber el motivo de su decisión de prohibir que las clases derivadas anulen las funciones de la clase base.
En su ejemplo, ninguna función se anula. En cambio, está escondido (es una especie de caso de sobrecarga degenerado). El error está en el código de clase Child. Como sugirió csmba, todo lo que puede hacer es cambiar la configuración del compilador (si es posible); debería estar bien siempre que no use una biblioteca de terceros que oculte sus propias funciones.
Técnicamente puede evitar que las funciones virtuales sean anuladas. Pero nunca podrás cambiar o agregar más. Eso no es ayuda completa. Es mejor usar el comentario frente a la función como sugiere faq lite.
Para aclarar, la mayoría de ustedes entendió mal su pregunta. Él no está preguntando sobre "anular" un método, él está preguntando si hay una manera de evitar "esconderse" o no. Y la respuesta simple es que "¡no hay ninguno!".
Aquí está su ejemplo una vez más
La clase para padres define una función:
int foo() { return 1; }
La clase secundaria, heredando el elemento primario, define la misma función OTRA VEZ (sin anular):
int foo() { return 2; }
Puedes hacer esto en todos los lenguajes de programación. No hay nada que impida la compilación de este código (excepto una configuración en el compilador). Lo mejor que obtendrá es una advertencia de que está ocultando el método de los padres. Si llama a la clase hija e invoca el método foo, obtendrá 2. Usted prácticamente ha roto el código.
Esto es lo que está preguntando.
Estaba buscando lo mismo y ayer llegué a esta pregunta [bastante antigua].
Hoy encontré una clara palabra clave c ++ 11: final
. Pensé que podría ser útil para los próximos lectores.
Cuando puede usar el especificador final
para métodos virtuales (introducido con C ++ 11), puede hacerlo. Permítanme citar mi sitio doc favorito :
Cuando se usa en una declaración de función virtual, final especifica que la función no puede ser anulada por las clases derivadas.
Adaptado a su ejemplo que sería como:
class Base {
public:
virtual bool someGuaranteedResult() final { return true; }
};
class Child : public Base {
public:
bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};
Cuando se compila:
$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’
Cuando trabaje con un compilador de Microsoft, también eche un vistazo a la palabra clave sealed
.