2013-08-28 23 views
21

taban sınıfını belirtmiyor Bunun için google'da isabet bulmakta zorlanıyorum. clang 3.2 Onüye başlatıcısı, statik olmayan bir veri üyesi veya

struct a { 
    float m_x; 
    float m_z; 
public: 
    a(float x): m_x(x) {} 
}; 

class b : public a { 
    b(float z): m_z(z) {} 
}; 

:

error: member initializer 'm_z' does not name a non-static data member or base class 
    b(float z): m_z(z) {} 
+0

Neden? Henüz "kötü bir miras elmas" yapmadım. @AndreyT bu sorunun cevabını kabul eden bir cevap vermek için bir üstat. Benim bir tane var ... Sanırım üye sinemacı değil, üstat sınıfını arıyor olmalıyım. tamam. –

+0

@WhozCraig: Sanal bir temel olsa bile, * dolaylı * üyeleri başlatmanıza izin vermez. Sanal devralma, dolaylı * tabanların * başlatılmasını gerektirebilir, ancak üye olmamalıdır. – AnT

+1

@Steven Lu: Kabul edilen cevap “a :: m_z” nin sadece a 'yapıcısı başlatıcı listesinden başlatılabileceğini söylüyor. B'nin yapıcı başlatıcısı listesinde (kodunuzda olduğu gibi) belirtilemez.Dil buna izin vermiyor. Mesele bu. Yani 'a' yapıcısına m_z' için (m_x' için yaptığınız gibi) özel olarak bir başka parametre eklemeniz ve başlangıç ​​değerinin bu kurucudan "b" değerini geçmeniz gerekir. BTW, yukarıdaki kodunuzda, 'a' b kurucusunun yapıcısına atıfta bulunmalısınız. Aksi takdirde, 'a' içinde varsayılan kurucunuz olmadığından derleme yapmaz. – AnT

cevap

26

Hayır doğrudan başlatıcı listeden taban sınıfı üyelerini başlatılamıyor.

Bu şekilde başlatma ilerledikçe sırası

C++ Standart n3337 §, başlatma ilerler sırası olmayan bir yetki verme yapıcısında

12.6.2/10 Aşağıdaki Bunun nedeni, - İlk ve sadece en fazla türetilmiş sınıfın (1.8) kurucusu için, sanal taban sınıfları, sırasına göre başlatılırlar, yönlendirilmiş taban c'nin asiklik grafiğinin derinlikteki ilk soldan sağa geçişi üzerinde görünürler. “soldan sağa”, türetilmiş sınıf taban belirleyici listesindeki temel sınıfların görünümü olan sırasının olduğu lasses.

- bunlar (bakılmaksızın mem-başlatıcıları arasında bulunur) baz belirteci-listesinde görünür olarak Daha sonra, doğrudan temel sınıfları beyan amacıyla başlatılır.

- Sonra , statik olmayan veri üyeleri (yine bakılmaksızın Mem-başlatıcıları düzeyindedir) sınıf tanımında ilan edildi sırayla başlatılır.

- Son olarak, yapıcı gövdesinin bileşik deyimi yürütülür.

[Not: üye alt nesnelerinin başlatmasının ters sırasına göre yok edilmesini sağlamak için bildirim sırası zorunludur. - uç not]

Yani bir temel sınıf (o korunabilir) bir yapıcı belirtmek ve türetilmiş sınıfa (should be preferred) başlatma listesinde Şunu kullanın veya bir temel sınıf üyesine atayabilirsiniz olabilir türetilmiş sınıftaki ctor gövdesinde (farklı davranışlar, farklı etkiler ve daha az etkilidir) varsayılan olarak başlatılmış (zaten değeri olan) üyeye atandığınız). İlk durumda

Eğer bu şekilde yazabiliriz:

struct A { 
    float m_x; 
    float m_z; 
    A(){} 
protected: 
    A(float x): m_x(x) {} 
}; 

class B : public A { 
public: 
    B(float z) : A(z) {} 
    // alternatively 
    // B(float z) { 
    //  m_x = z; 
    // } 
}; 

int main(){ 
    B b(1); 
    return 0; 
} 
İlgili konular