estándar de C++ sí garantiza un pedido de listas de inicialización (ISO C++ estándar 12.6.2/5):
... miembros de datos estáticos se inicializan en el orden en que se declaran en el definición de clase (de nuevo, independientemente del orden de los iniciadores de memoria ).
(Ver Wyatt Anderson's answer para obtener más información.)
Ejemplo:
class Foo
{
public:
Foo();
private:
A a;
B b;
C c;
};
Foo::Foo() : b(), a(), c()
{
// a is initialized first, then b, then c - NOT b, a, then c!
}
Sin embargo, no se puede inicializar una variable dos veces - lo que tiene no se compilará.
class X //() what's with the pair of parentheses you have in your code snippet?
{
public:
X();
private:
X_Implementation* impl_;
};
X::X() :
impl_(Allocate(sizeof(X_Implementation))),
// It is not allowed to initialize a data member twice!
impl_(Construct<X_Implementation>(impl_))
{
}
En su lugar, sólo hay que poner el trabajo extra en el constructor:
X::X() : impl_(Allocate(sizeof(X_Implementation)))
{
impl_ = Construct<X_Implementation>(impl_);
}
Puede haber problemas de seguridad excepción con el código anterior, pero sin saber qué Allocate()
o Construct()
realmente hace que' m no puedo decir. Te puedo decir que es mejor separar la asignación y la construcción en sus propias clases si lo hace, mediante el Recursos adquisición es de inicialización (RAII) idioma:
class XBase
{
protected:
XBase() : impl_(Allocate(sizeof(X_Implementation)))
{
}
~XBase()
{
if(impl_ != 0) { Deallocate(impl_); } // Or something like this
}
X_Implementation* impl_;
};
class X : private XBase // XBase is an implementation detail
{
public:
X()
{
impl_ = Construct<X_Implementation>(impl_);
}
~X()
{
Destruct<X_Implementation>(impl_); // Or something like this
}
};
esta manera, si Construct()
se produce una excepción, no perderá memoria ya que se llamará al destructor de la clase base que desasignará la memoria apuntada por impl_
. Esto es importante porque si la excepción no se captura y sale del constructor, su destructor correspondiente no se llamará. Véase el documento de Bjarne Stroustrup en la seguridad excepción: http://www2.research.att.com/~bs/except.pdf
Utilice la ubicación nueva para construir en un búfer de memoria que haya asignado previamente. –
No se puede inicializar un objeto más de una vez, por lo que esta pregunta no es sequitur. Más allá de eso, obvio duplicado de [Constructor initialization-list evaluation order] (https://stackoverflow.com/questions/1242830/constructor-initialization-list-evaluation-order) –