2011-01-09 19 views
39

Tengo una clase que es para escuchar los eventos del mouse. Sin embargo, no quiero obligar al usuario a implementar ninguno específico, pero sí quiero dejar en claro que deben heredarlo.Haciendo una clase abstracta sin ningún método virtual puro

¿Hay alguna manera de hacerlo?

Gracias

+1

Curioso: Java's MouseAdapter es exactamente lo que estás planeando escribir: una clase abstracta sin ningún método virtual puro para que las personas puedan elegir libremente cuáles de los métodos de escucha desean implementar y cuáles no. –

+2

¿Importa realmente si alguien crea una instancia de la clase base y la registra como un detector de mouse? Es de suponer que simplemente ignorará todo (o realizará acciones predeterminadas para todo), exactamente lo mismo que si se hubieran tomado la molestia de escribir el código para heredar de su clase pero no implementar ninguna de las funciones. Dos formas diferentes de hacer algo sin sentido en lugar de uno. –

Respuesta

47

Puede declarar un destructor virtual puro, pero darle una definición. La clase será abstracta, pero las clases heredadas no serán abstractas por defecto.

struct Abstract 
{ 
    virtual ~Abstract() = 0; 
}; 

Abstract::~Abstract() {} 

struct Valid: public Abstract 
{ 
     // Notice you don't need to actually overide the base 
     // classes pure virtual method as it has a default 
}; 


int main() 
{ 
    // Abstract  a; // This line fails to compile as Abstract is abstract 
    Valid   v; // This compiles fine. 
} 
+2

Puede dar un ejemplo, lo intenté, pero mis subclases se vuelven abstractas. – jmasterx

+0

@Milo http://programmers.stackexchange.com/questions/35038/what-can-i-do-when-the-interviewer-doesnt-know-the-answer-to-his-her-own-questio/35043 # 35043 –

+0

@Philip: Incorrecto. La clase heredera deberá proporcionar una implementación, de lo contrario seguirán siendo abstractos. – AbdullahC

38

Especificar el constructor de la base como protegido. Esto significa que no puedes construirlo directamente, sino que obliga a la herencia. ¡Sin embargo, no hay nada que haga que un desarrollador herede de esa clase, además de una buena documentación!

1

¿Por qué le gustaría que el usuario herede, si no tiene que implementar nada?

Cuando se necesita la clase base para poder poner todos los "manejadores de eventos" en un conjunto estándar. Entonces nadie puede crear una clase y ponerla en este conjunto sin subclasificar su clase base. Porque el conjunto se definirá como

std::set<MyBaseClass*> mySet; 
+1

Quizás el usuario no esté heredando, pero dos clases distintas que ofrecen miembros exclusivos a la vez que tienen una base común tienen sentido. HttpTransaction-> HttpRequest, HttpTransaction-> HttpResponse, etc. –

3

Puede declarar que su clase base tiene un destructor virtual puro que usted implementa. Como el compilador siempre proporciona un destructor, la clase derivada no será puramente virtual, pero la clase base no se puede instanciar directamente. Como siempre debes declarar un destructor virtual si tu clase tiene un método virtual, esto no implica ningún costo.

class Base 
{ 
public: 
    virtual ~Base() = 0; 
    virtual void SomeVirtualMethod(); 
}; 

inline Base::~Base() 
{ 
} 

class Derived : public Base 
{ 
}; 

inline Base* createBase() 
{ 
    // return new Base; // <- This won't compile 
    return new Derived; // <- This compile, Derived is not a pure virtual class ! 
} 
1

Por definición, una clase abstracta es una clase que tiene al menos una función virtual pura. Para su propósito, se puede definir el destructor ser puro virtual y proporcionar una implementación:

class abstract { 
     virtual ~abstract()=0; 
}; 

abstract::~abstract() {} 

Por defecto, todas las clases que heredan no va a ser abstracta, a pesar de que no tendrán que implementar cualquier método.

Cuestiones relacionadas