2010-12-16 31 views
10

¿Cómo puedo hacer cumplir que un método de clase base no está siendo anulado por una clase derivada?¿Cómo evitar que un método sea anulado en la clase derivada?

+5

No haga es virtual en la clase base? Entonces no puede ser anulado, solo sobrecargado. No existe un equivalente directo a los métodos "finales" de Java, si esa es la pregunta. –

+0

así que sin usar una palabra clave virtual no podemos hacerlo, entonces ¿cómo implementaron en JAVA luego – sriks

+0

en Java, marcando un método 'final' prohíbe a las subclases implementar ese método, y el compilador y/o el verificador de código de bytes aplicarán esto . En C++, no hay forma de prohibirlo, es solo que por definición de "anulación", solo las funciones virtuales pueden ser "anuladas". –

Respuesta

14

Si hace que el método no sea virtual, las clases derivadas no pueden anular el método. Sin embargo, una clase no puede anular un método de una clase base, y también previene que otras clases derivadas anulen el mismo método. Una vez que el método es virtual, se mantiene virtual.

+1

+1: Sin embargo, la parte fue clave para mí. – imallett

+4

con C++ 11 puede utilizar el especificador final para evitar que se anule un método en las clases derivadas – tharinduwijewardane

1

bien si quieres mantenerlo público, no lo declares virtual.

EDIT: Srikanth comentó que se preguntaba sobre anular una función miembro privada en una clase derivada.

class A 
{ 
public: 
    virtual ~A(){}; 
    void test() 
    { 
     foo(); 
    }; 
private: 
    virtual void foo() 
    { 
     std::cout << "A"; 
    }; 
}; 


class B : public A 
{ 
public: 
    virtual void foo() 
    { 
     std::cout << "B"; 
    }; 
}; 


void test() 
{ 
    B b; 
    A& a = b; 

    a.test(); // this calls the derived B::foo() 

    return 0; 
}` 
+3

Las clases derivadas aún pueden anular las funciones de miembros privados virtuales. –

+0

He editado, gracias por la corrección. –

+0

, pero ¿cómo podemos anular un método privado sin hacer que el derivado sea un amigo o disminuir el especificador de acceso – sriks

2

No lo hagas virtual.

Esto no impedirá derivar de su clase y ocultar la función (proporcionando otra función miembro con el mismo nombre). Sin embargo, si su clase no está destinada a ser derivada de todos modos (sin destructor virtual, sin funciones de miembros virtuales), eso no debería ser un problema.

-1

Respuesta breve: no hay necesidad de eso. Larga respuesta que puede hacer some twists, pero ¿vale la pena?

18

Si puede utilizar el especificador final de C++ 11, puede evitar que las clases derivadas anulen ese método. (Compiladores de Microsoft parecen apoyar la similares sealed con una semántica similar.)

He aquí un ejemplo:

#include <iostream> 

struct base { 
    // To derived class' developers: Thou shalt not override this method 
    virtual void work() final { 
     pre_work(); 
     do_work(); 
     post_work(); 
    } 
    virtual void pre_work() {}; 
    virtual void do_work() = 0; 
    virtual void post_work() {}; 
}; 

struct derived : public base { 
    // this should trigger an error: 
    void work() { 
     std::cout << "doing derived work\n"; 
    } 
    void do_work() { 
     std::cout << "doing something really very important\n"; 
    } 
}; 

int main() { 
    derived d; 
    d.work(); 
    base& b = d; 
    b.work(); 
} 

Esto es lo que me sale cuando intento compilar:

$ g++ test.cc -std=c++11 
test.cc:17:14: error: virtual function ‘virtual void derived::work()’ 
test.cc:5:22: error: overriding final function ‘virtual void base::work()’ 
+0

Pregunta: ¿Por qué debería declarar "trabajo()" como "virtual" cuando no quiero que se anule en clases derivadas? ¿Por qué no simplemente marcarlo como final? – Sonic78

+0

@ Sonic78 ¡Buena pregunta!En el código del mundo real, puede tener otra clase base para 'base', que proporciona una función virtual que desea evitar que se anule en clases derivadas de su base intermedia. – moooeeeep

Cuestiones relacionadas