2010-02-18 15 views
111

Ebeveyn sınıfı korumalı olarak bildirilen veri üyelerini başlatmak için bir alt sınıf 'kurucusunun başlangıç ​​listesini kullanmak mümkün müdür? İşe yaratamıyorum. Etrafında çalışabilirim, ama mecbur olmasaydım güzel olurdu.Ebeveynin korumalı üyelerini başlatma listesiyle başlat (C++)

Bazı örnek kod:

class Parent 
{ 
protected: 
    std::string something; 
}; 

class Child : public Parent 
{ 
private: 
    Child() : something("Hello, World!") 
    { 
    } 
}; 

Bunu çalıştığınızda, derleyici söylüyor: "Sınıf 'Çocuk' 'şey' olarak adlandırılan alan yoktur". Böyle bir şey mümkün mü? Eğer öyleyse, sözdizimi nedir?

Çok teşekkürler!

cevap

103

Tanımladığınız şekilde mümkün değil. Birlikte iletmek için temel kuruma bir kurucu (korunabilir) eklemeniz gerekecek. Sen türetilmiş sınıf yapıcı başlatma listesinde üst sınıfın üyeleri başlatılamıyor olabilir

class Parent 
{ 
protected: 
    Parent(const std::string& something) : something(something) 
    {} 

    std::string something; 
} 

class Child : public Parent 
{ 
private: 
    Child() : Parent("Hello, World!") 
    { 
    } 
} 
+2

"kullanarak" anahtar kelime kullanarak bu şekilde deneyebilirsiniz. En azından şimdi yapılıp yapılamayacağı konusunda endişelenmem gerekmiyor. :) – Stephen

11

: gibi bir şey. Korunmanın, kamuoyunun veya başka bir şeyin önemi yok. Örnekte

, üye something sadece Parent sınıfın yapıcı başlatıcısı listesinde başlatıldı anlamına gelir Parent sınıf üyesidir.

51

Derleyici başlatıcı listesiyle karşılaştığında, türetilmiş sınıf nesnesi henüz oluşturulmamış. Temel sınıf kurucusu o zamana kadar çağrılmamıştır. Sadece temel sınıf kurucusu çağrıldıktan sonra, something oluşmaya gelir. Bu yüzden sorun. Temel sınıf yapıcısını açıkça çağırmazsanız, derleyici bunu sizin için yapar (temel sınıf için uygun önemsiz yapıcıyı oluşturarak). Bu, something üyesinin varsayılan olarak başlatılmasına neden olur.

C itibaren

++ 0x taslak:

12.6.2 başlatılıyor bazlar ve üyeler bir Mem-başlatıcı-id içinde

İsimler kapsamında aranır yapıcının sınıfı ve bu kapsamda bulunamadıysa, yapıcının tanımını içeren kapsamına bakın. [Not: şantiye sınıfı, tek bir tanımlayıcı oluşan elemanı veya baz isimlendirme Mem-başlatıcı kimliği ve bunlara atıfta bulunan, bir doğrudan ya da sınıfın sanal temel sınıf olarak aynı isimde bir üye içeriyorsa sınıf üyesine Gizli temel sınıfı için bir momenitializer-kimliği nitelikli adı kullanılarak belirtilebilir. -end not] Mem-başlatıcı-id isimlerin sürece şantiye sınıf, bir statik olmayan veri şantiye sınıfının üyesi ya da bu sınıfın bir doğrudan veya sanal baz Mem-başlatıcı kötü şekillendirilmiş olan .

Not: Vurgulamak benim.

+2

"Neden" de bana işaret ettiğin için teşekkürler. Tamamen mantıklı. C++ 'dan çok uzun bir süredir uzaktayım ... :) – Stephen

0

Belki Bu tam olarak benim zaten bulurdu geçici çözüm olduğunu

class Parent 
{ 

protected: 
std::string something; 
}; 

class Child : public Parent 
{ 

private: 
using Parent::something; 
Child() 
{ 
    something="Hello, World!"; 
} 
};