Pregunta

¿Alguien conoce alguna característica o técnica del lenguaje en C++ para evitar que una clase secundaria anule un método particular en la clase principal?

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 obtiene es una advertencia en tiempo de compilación sobre cómo ocultar la función X heredada no virtual.

¿Fue útil?

Solución

Un par de ideas:

  1. Haz que tu función sea privada.
  2. No hagas tu función virtual.Sin embargo, esto en realidad no evita que la función quede ensombrecida por otra definición.

Aparte de eso, no conozco ninguna característica del lenguaje que bloquee 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!

Otros consejos

Cuando puedes usar el final especificador para métodos virtuales (introducido con C++ 11), puede hacerlo.Déjame citar mi sitio de documentación favorito:

Cuando se usa en una declaración de función virtual, final especifica que la función no puede ser anulada por clases derivadas.

Adaptado a su ejemplo, 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 esté trabajando con un compilador de Microsoft, eche también un vistazo al sealed palabra clave.

Parece que lo que estás buscando es el equivalente del lenguaje Java. final palabra clave que evita que un método sea anulado por una subclase.

Como otros aquí tienes sugirió, realmente no puedes evitar esto.Además, parece que esto es bastante preguntas frecuentes.

(a) No creo que hacer que la función sea privada sea la solución porque eso simplemente 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 la clase derivada mediante enlace en tiempo de compilación, es decir, obj.someFunction() donde obj es una instancia de clase derivada.

No creo que haya una manera de hacer esto. Además, me gustaría saber el motivo de su decisión de prohibir que las clases derivadas anulen las funciones de la clase base.

Para aclarar, la mayoría de ustedes no entendieron bien su pregunta.No pregunta acerca de "anular" un método, sino si hay una manera de evitar "ocultar" o no.Y la respuesta sencilla es que "¡no hay ninguno!".

Aquí está su ejemplo una vez más.

La clase principal define una función:

int foo() { return 1; }

La clase secundaria, al heredar el padre, 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 que este código se compile (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 llamas a la clase secundaria e invocas el método foo, obtendrás 2.Prácticamente has descifrado el código.

Esto es lo que pregunta.

una advertencia en tiempo de compilación sobre cómo ocultar la función X heredada no virtual.

cambie la configuración del compilador para que sea un error en lugar de una advertencia.

¡Supongo que lo que te advierte el compilador es que se esconde!¿Se está realmente anulando?

El compilador puede darle una advertencia, pero en tiempo de ejecución, se llamará al método de la clase principal si el puntero es del tipo clase principal, independientemente del tipo real del objeto al que apunta.

Esto es interesante.Intente crear un pequeño programa de prueba independiente para su compilador.

Estaba buscando lo mismo y ayer llegué a esta pregunta [bastante antigua].

Hoy encontré una palabra clave interesante en C++11: final .Pensé que podría ser útil para los próximos lectores.

http://en.cppreference.com/w/cpp/language/final

Si aborda la clase secundaria como un tipo de su clase principal, entonces una función no virtual llamará a la versión de la clase principal.

es decir:

Parent* obj = new Child();

A menos que haga que el método sea virtual, la clase secundaria no puede anularlo.Si desea evitar que las clases secundarias lo llamen, hágalo privado.

Entonces, por defecto, C++ hace lo que quieres.

Intentar evitar que alguien use el mismo nombre que su función en una subclase no es muy diferente a intentar evitar que alguien use el mismo nombre de función global que ha declarado en una biblioteca vinculada.

Sólo puede esperar que los usuarios que deseen utilizar su código, y no el de otros, tengan cuidado con la forma en que hacen referencia a su código y utilicen el tipo de puntero correcto o utilicen un alcance totalmente calificado.

En su ejemplo, no se anula ninguna función.En cambio, está oculto (es una especie de caso degenerado de sobrecarga).El error está en el código de la 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 y cuando no utilices una biblioteca de terceros que oculte sus propias funciones.

Técnicamente, puedes evitar que se anulen funciones virtuales.Pero nunca jamás podrás cambiar o agregar más.Eso no es de gran ayuda.Es mejor utilizar el comentario delante de la función como sugiere Faq Lite.

Los métodos de C++ son privados y no se pueden anular de forma predeterminada.

  • No puedes anular un método privado
  • No puede anular un documento que no seavirtual método

¿Quizás te refieres a la sobrecarga?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top