Bjarne Stroustrup ha escrito sobre esta here.
El bit relevante desde el enlace:
¿Puedo evitar que la gente se deriva de mi clase?
Sí, pero ¿por qué quieres? Hay dos respuestas comunes:
- por eficiencia: para evitar que mi función las llamadas sean virtuales.
- para la seguridad: para asegurarse de que mi clase no se utiliza como una clase base (por ejemplo, para asegurarse que puedo copiar objetos sin temor de rebanar)
En mi experiencia, la eficiencia la razón usualmente es un miedo fuera de lugar. En C++, las llamadas a funciones virtuales son tan rápidas que su uso en el mundo real para una clase diseñada con funciones virtuales no produce gastos generales mensurables en tiempo de ejecución en comparación con soluciones alternativas que utilizan llamadas a funciones ordinarias. Tenga en cuenta que el mecanismo de llamada a la función virtual se usa generalmente solo cuando se llama a través de un puntero o una referencia. Cuando se llama a una función directamente para un objeto nombrado, la sobrecarga de la clase de función virtual se optimiza fácilmente.
Si existe una necesidad real de "limitar" una jerarquía de clases para evitar llamadas a funciones virtuales, uno podría preguntarse por qué esas funciones son virtuales en primer lugar. He visto ejemplos donde las funciones críticas para el rendimiento se han hecho virtuales sin una buena razón, simplemente porque "esa es la forma en que generalmente lo hacemos".
La otra variante de este problema, cómo evitar la derivación por razones lógicas, tiene una solución. Desafortunadamente, esa solución no es bonita. Se basa en el hecho de que la clase más derivada en una jerarquía debe construir una base virtual. Por ejemplo:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
(de D&E seg 11.4.3).
Ah, ¿y ese podría ser un método de fábrica estático de mi clase para mantener las cosas juntas? Suena muy bien. – SebastianK
Desafortunadamente, esto no detiene la derivación.Simplemente evita la instalación del tipo derivado, excepto a través de la fábrica. Sería bueno si pudieras prevenir la derivación, pero hasta donde yo sé, no puedes. –
¿De qué manera práctica hay una diferencia entre no poder instanciar un objeto del tipo derivado y no poder obtener nada (acceso a miembros estáticos protegidos?) – Motti