C++ standart başlatma listeleri için bir emir (ISO C++ Standart 12.6.2/5) garanti yapar:
... nonstatic veri üyeleri onlar ilan edildi sırayla başlatıldı edilecektir sınıf tanımı (yine mem başlatıcılarının sırasına bakılmaksızın).
(Daha fazla bilgi için Wyatt Anderson's answer bakınız.)
Örnek:
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!
}
Ancak, iki kez, bir değişkene başlangıç olamaz - Eğer derleme olmaz bağlar var.
X::X() : impl_(Allocate(sizeof(X_Implementation)))
{
impl_ = Construct<X_Implementation>(impl_);
}
yukarıdaki kod ile, ama aslında ben ne Allocate()
veya Construct()
bilmeden istisna güvenlik sorunları olabilir':
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_))
{
}
Bunun yerine, sadece yapıcı içine fazladan iş koymak söyleyemiyorum. Ben bunu yaparsanız bunun kendi sınıflara ayırma ve ayrı ayrı yapılması en iyisi olduğunu söyleyebilirim, o deyim
Kaynak Edinme Is Başlatma (RAII) kullanılarak: 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
}
};
Bu şekilde, Construct()
bir istisna atar,, Temel sınıf yıkıcısı çağrılacağından hafızayı kaçırmayacaksınız, bu da impl_
ile işaretlenmiş belleği kaldıracaktır. Bu önemlidir, çünkü istisna yakalanmaz ve kurucudan ayrılırsa, eşleştiricisi , olarak adlandırılamaz. İstisna güvenliği konusunda Bjarne Stroustrup'un kağıdı bakınız: ISO/IEC göre http://www2.research.att.com/~bs/except.pdf
Daha önce ayırdığınız bir bellek arabelleği oluşturmak için yeni yerleşimi kullanın. –
Bir nesneyi birden çok kez başlatamazsınız, bu nedenle bu soru bir dizisizdir. Bunun ötesinde, [Oluşturucu başlatma listesi değerlendirme sırası] 'nın açık bir kopyası (https://stackoverflow.com/questions/1242830/constructor-initialization-list-evaluation-order) –