2009-03-27 13 views
5

Sınıf hiyerarşisi var. Temel sınıf, dosyadan yüklenebilen (ve çalışma süresi boyunca yeniden yüklenebilen) bazı ayarlama parametrelerini kullanır. Her türetilmiş sınıf, bazı ek parametreler ekleyebilir. Temel kurucuya doğru boyutta bir parametre dizisi tahsis etmenin bir yolunu arıyorum, böylece türetilmiş sınıfta tahsis etmek ve yeniden tahsis etmek zorunda kalmam. Böyle bir şey bekliyordum, ama (parametreler her zaman 2 elemanı vardır) çalışmıyor:Türetilmiş sınıfa dayalı olarak temel yapıcıda dizi nasıl ayrılır?

class Base 
    { static int nParms; 
    virtual int getNParms() { return nParms;} 
    float *parameters; 
    public: 
    Base() 
    { parameters= new float[this->getNParms()]; 
     parameters[0] = globalReloadableX; 
     parameters[1] = globalReloadableY; 
    } 
    }; 
    int Base::nParams =2; 

    class Derived : public Base 
    { static int nParms; 
    virtual int getNParms() { return nParms;} 
    public: 
    Derived() : Base() 
    { parameters[2] = globalReloadableZ; 
    } 
    } 
    int Derived::nParams =3; 

Ben this question gördüm ama çözüm benim için oldukça işe orada buna gerek yoktur. Ayrıca parametreleri düzenli her sınıfta dizi yapmadan çalıştı:

class Base 
    { float parameters[2] 
    ... 
    class Derived : public Base 
    { float parameters[3] 
    ... 

ama bu Türetilmiş yapar 2 ayrı diziler var.

Herhangi bir fikrin var mı?

cevap

5

Neden temel dizi yapıcısında gerekli dizi boyutunu parametre olarak geçmiyorsunuz?

(yani C++ sanal fonksiyonlar nasıl çalıştığını çünkü sanal fonksiyon türetilmiş sınıf çağırmaz sebebi;., Kavramsal olarak türetilmiş sınıf yapıcısı tamamlanıncaya kadar, nesnenin tipi hala temel sınıftır)

+0

Neden değil? Çok açık! Bazen detaylara çok fazla sarılıyorum ... Nedenini açıkladığın için teşekkürler. – AShelly

+0

Sorun değil, herkese olur! –

2

Boyutu bir parametre yapmaya ne dersiniz?

class Base 
{ static int nParms; 
    virtual int getNParms() { return nParms;} 
    float *parameters; 
public: 
    Base(int n = nParams) 
    { parameters= new float[n]; 
    parameters[0] = globalRelodableX; 
    parameters[1] = globalRelodableY; 
    } 
}; 
int Base::nParams =2; 

class Derived : public Base 
{ static int nParms; 
    virtual int getNParms() { return nParms;} 
public: 
    Derived() : Base(nParams) 
    { parameters[2] = globalRelodableZ; 
    } 
} 
int Derived::nParams =3; 
2

Neden bir dizi kullanıyorsunuz? Std :: vektörü, türetilmiş sınıfta gerektiği kadar param kullanılmasına izin verir, üstelik, kaçının ihtiyaç duyduğunu bilmeden (veya önemsemede).

+0

Bu iyi bir nokta. Aslında diğer yerlerde vektörleri kullanıyorum. Ama hala C'deki çalışmamın çoğunu yapıyorum, bu yüzden özellikleri eklerken bildiğim şeylere gitmeye eğilimliyim ... – AShelly

0

std :: map kullanmayı düşünürüm. Baz ile büyüyebilir ve diğerlerinin kullandığı parametre sayısını önemsemeden türetilebilir. Anahtar/değer çiftleri, sayısal indeksleri yönetmek için muhtemelen daha kolay olsa da, bu uygulama açıkça bağımlıdır.

0

Neye bağlı olarak hem Earwicker hem de Steve'in cevaplarını beğeniyorum. Bu nesnelerin çoğu sık sık oluşturulup imha ediliyorsa, o zaman minimum bellek ayırma miktarını ve dolayısıyla Earwicker'ın daha üstün olmasını istiyorsunuz. Bununla birlikte, eğer bu genellikle "yaratılmış ve nadiren yeniden yapılmış" bir şeyse, o zaman haritaların genellikle çalışmak için çok daha kolay olduğu ve ihtiyaç duyulduğunda dinamik bir şekilde büyüdüğü için Steve'in cevabı ile giderdim, ancak muhtemelen çok fazla yük varsa Bu nesne çok şey yapılmakta ve yok edilmektedir.

2

Başkaları tarafından önerilen şekilde, yapıcı için bir parametre haline getirebilirsiniz, ancak Base'yi parametre olarak büyüklükte bir şablon sınıfı haline getirebilirsiniz. Bu, yığında tahsis edilecek diziye olan gereksinimi ortadan kaldırmak gibi birçok avantajı vardır:

template <size_t nParams> 
class Base 
{ 
    float parameters[nParams]; 
public: 
    Base() 
    { // could use a static_assert(nParams > 1) here... 
     parameters[0] = globalRelodableX; 
     parameters[1] = globalRelodableY; 
    } 
}; 

class Derived : public Base<3> // or whatever 
{ 
public: 
    Derived() 
    { parameters[2] = globalRelodableZ; } 
}; 
İlgili konular