2010-11-12 15 views
25

Benim bağırsak hislerim değil.Kurucu başlatıcı listesinde bir işlevi çağırmak tamam mı?

class PluginLoader 
{ 
    public: 
     Builder* const p_Builder; 
     Logger* const p_Logger; 

     //Others 
}; 

PluginLoader::PluginLoader(Builder* const pBuilder) 
    :p_Builder(pBuilder), p_Logger(pBuilder->GetLogger()) 
{ 
    //Stuff 
} 

Ya yapıcı değiştirip PluginLoader inşa yerden bir Logger* const geçmelidir: Aşağıdaki durumdayım?

cevap

27

Bu gayet iyi ve normaldir. Daha önce p_Builder başlatıldı.

+0

Gee. Ben bir kapı olmamalıyım. :) – nakiya

+11

Daha da fazlası, pBuilder-> GetLogger() 'yi değil, p_Builder-> GetLogger()' yi çağırıyor. Her ikisi de yasaldır, ancak ikincisi sınıf tanımında yeniden sıralanan örnek değişkenine duyarlıdır. – Eclipse

+0

@Eclipse: Oh, onu görmedim bile. @nakiya: Üye veya parametreyi kullanmak mı demek istediniz? Ya güvenli olduğu gibi. – GManNickG

0

Mükemmel iyi uygulama.

bu öneririm (ama onun tamamen kişisel düzeyde):

yerine yapıcı denilen işlevleri sahip, grubun onları bir init işlevinde, yalnızca esneklik amaçlı: Daha sonra oluşturmak zorunda olmadığını diğer kurucular.

+3

Önerileriniz, kurucudan aradığınız bir * private * 'init' işleviyse, bunun için pek umurumda değil ama sanırım sorun yok. Önerirseniz, sınıfın kullanıcıları tarafından çağrılması gereken bir * public * 'init 'işlevi, hatalara ve tutarsızlıklara eğilimlidir (bir nesne oluşturduktan sonra, henüz geçersiz bir durumda olur ve kullanıcı unutabilir 'init'i çağırmak veya yapı ile başlatma arasındaki nesneyi kullanmayı denemek için ...) –

+0

bir sahte üye kullanabilir ve init yönteminin bir tür döndürmesini sağlayabilirsiniz.Örneğin, 'class IDGenerator public: IDGenerator(); bool sıfırlama(); std :: uint32_t generate(); özel: bool mReset; T_ID_set mIds; std :: uint32_t mId; }; IDGenerator :: IDGenerator() : mReset (reset()) { } BOOL IDGenerator :: sıfırlama() { mIds.clear(); mId = 0; , true; } ' – dgsomerton

19

Neyin var? Ancak, ben sadece bunu yapmamayı dikkatli olmak uyarmak istiyorum: Ben kodunuzu 2 değişiklikler yaptı

class PluginLoader 
{ 
    public: 
     Logger* const p_Logger; // p_Logger is listed first before p_Builder 
     Builder* const p_Builder; 

     //Others 
}; 

PluginLoader::PluginLoader(Builder* const pBuilder) 
    :p_Builder(pBuilder), 
    p_Logger(p_Builder->GetLogger()) // Though listed 2nd, it is called first. 
             // This wouldn't be a problem if pBuilder 
             // was used instead of p_Builder 
{ 
    //Stuff 
} 

Not (Gman bu ima, sadece kendini temize yapmak istedim). İlk olarak, sınıf tanımında, p_Builder'den önce p_Logger'i beyan ettim. İkincisi, parametre yerine p_Logger'ı başlatmak için p_Builder üyesini kullandım.

Bu değişikliklerden biri iyi olabilir, ancak birlikte bir hata çıkarırlar, çünkü p_Logger ilk önce başlatılır ve başlatılmamış p_Builder'ı kullanarak onu başlatmak için kullanırsınız.

Her zaman, üyelerin sınıf tanımında göründükleri sırayla başlatıldığını unutmayın. Ve bunları başlatma listenizde koyduğunuz sırayla alakasız.

İlgili konular