¿Cómo inicializar los miembros protegidos de una clase base abstracta?
-
13-11-2019 - |
Pregunta
Tal vez me estoy preocupando por nada.Yo deseo que los miembros de datos para seguir de cerca el RAII idioma.¿Cómo puedo iniciar un protegidas puntero miembro de una clase base abstracta a null?
Sé que debe ser nulo, pero ¿no sería más agradable para asegurarse de que es universalmente entendido?
Poniendo el código de inicialización fuera de la lista de inicializador tiene el potencial de no ser ejecutado.Pensar en términos de las operaciones de montaje para asignar este puntero a la pila, no podían ser interrumpido en mucho la misma manera (como el c tor cuerpo) en multihilo entornos o es pila de expansión garantizados para ser atómicas?Si el destructor está garantizado a ejecutar, a continuación, no sería posible que la pila de expansión tienen una garantía, incluso si el procesador no lo realizan de forma atómica?
Cómo hizo una pregunta fácil de conseguir tan expansivo?Gracias.
Si podía evitar el std::la biblioteca que sería genial, yo estoy en un minimilist medio ambiente.
Solución
Tal vez usted está sobre-pensar esto.El siguiente ejemplo tiene el miembro base intialized a null:
struct Base
{
virtual ~Base() = 0; // or make something else pure; this is just an example
Base() : p() { } // p initialized to null
Base(Foo * q) : p(q) { } // another option
protected:
Foo * p;
};
struct Derived : private Base
{
// no extra work needed
// maybe something like this...
Derived(int a, bool c) : Base(new Foo(a * (c ? 2 : 3))) { }
};
La derivada constructor llama al constructor base primero, y que uno de ellos dice que Base::p
se inicializa a cero.
Otros consejos
Muy fácilmente: la mejor manera es usar los punteros inteligentes, realmente no evite el estándar, generalmente hace las cosas mejor que su implementación promedio.
class base{
public:
base() : a(new int(5)) {}
protected:
std::unique_ptr<int> a;
virtual ~base() {}
};
class child : public base {
child() : base() {}
~child() {} //a will automatically be deleted
};
Ahora en este caso, a menos que el niño utilice el puntero (que a menudo no es un gran diseño), entonces se puede hacer privado.
Otra forma sería eliminarlo manualmente en el destructor base
class base{
public:
base() : a(new int(5)) { } //base member init'd
protected:
int* a;
virtual ~base() { delete a; } //base member destroyed
};