[c++] ¿Cómo se define la clase sellada en C ++?


2 Answers

Hay dos formas, la simple barata y la correcta. Las dos respuestas de @Naveen y @Nawaz se refieren al correcto, que requiere la creación manual de una clase de sellador para cada clase que realmente desea sellar.

La forma no infalible, que se utiliza en las bibliotecas de adobe está utilizando una clase de plantilla para eso. El problema es que no puede declarar el argumento de la plantilla como un amigo, y eso significa que tendrá que pasar de la protected private a la protected menos segura:

template <typename T>
class sealer {
protected: sealer() {}
};
class sealed : virtual sealer<sealed> {};

Y puede automatizarlo con una macro (no recuerdo el sabor exacto de la macro en el código de Adobe):

#define seal( x ) virtual sealer<x>
class sealed : seal(sealed) 
{};

Ahora esto atrapará a las personas que equivocadamente intentan heredar sin saber que no deberían:

class derived : sealed {};
int main() {
   derived d;  // sealer<T>::sealer() is protected within this context
}

Pero no inhibirá a las personas que realmente desean derivar, ya que pueden obtener acceso al constructor derivando de la plantilla ellos mismos:

class derived : sealed, sealer<sealed> {};
int main() {
   derived d;
};

No estoy seguro de si esto cambiará en C ++ 0x, creo que recuerdo algunas discusiones sobre si una plantilla de clase podría ser amistosa con uno de sus argumentos, pero en una búsqueda superficial del borrador realmente no puedo decirlo. Si eso fue permitido, entonces esta sería una solución genérica bien:

template <typename T>
class sealer {
   sealer() {}
   friend class T; // Incorrect in C++03
};
Question

Cómo detener la clase para que sea heredada por otra clase.




No puedes. C ++ no es Java o C #. Y también no tiene sentido, nunca, en mi humilde opinión.




Basado en las preguntas frecuentes de http://www.stroustrup.com/bs_faq2.html#no-derivation Bjarne Stroustrup con pequeñas modificaciones sin el uso de palabras clave de amigos:

// SEALED CLASS DEFINITIONS
class Usable_lock {
protected:
    Usable_lock() {}
    Usable_lock(const Usable_lock&) {}
};
#define sealed_class private virtual Usable_lock

// SEALED CLASS USAGE EXMAPLES
class UsableLast : sealed_class {
public:
    UsableLast(){}
    UsableLast(char*){}
};
class DD : public UsableLast {};

// TEST CODE
template <class T> T createInstance() {
    return T();
}
int main()
{
    createInstance<UsableLast>();
//  createInstance<DD>();
    return 0;
}



Related