2009-03-27 7 views
5

Ho una gerarchia di classi. La classe base utilizza alcuni parametri di ottimizzazione caricabili dal file (e ricaricabili durante il runtime). Ogni classe derivata può aggiungere alcuni parametri aggiuntivi. Sto cercando un modo per allocare un array di parametri correttamente dimensionato nel costruttore base, in modo che non debba deallocare e riallocare nella classe derivata. Speravo in qualcosa di simile, ma non sta funzionando (parametri è sempre 2 elementi):Come allocare l'array nel costruttore di base con le dimensioni in base alla classe derivata?

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; 

Ho visto this question, ma la soluzione non ci funziona abbastanza per me. Ho provato anche fare una serie regolare i parametri in ogni classe:

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

ma che rende derivati ​​sono 2 array separati.

Qualche idea?

risposta

5

Perché non passare la dimensione dell'array richiesta come parametro nel costruttore della classe base?

(La ragione per la funzione virtuale non chiama la classe derivata è perché è così che funzionano funzioni virtuali C++;. Concettualmente, finché il costruttore della classe derivata completa, il tipo di oggetto è ancora la classe base)

+0

Perché no? Troppo ovvio! A volte mi ritrovo troppo nei dettagli ... Grazie per la spiegazione del perché. – AShelly

+0

Nessun problema, capita a tutti! –

2

Che ne pensi di rendere la dimensione un parametro?

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

Perché utilizzare un array? Il vettore std ti consentirà di utilizzare tutti i parametri necessari nella classe derivata, con la base che non conosce (o cura) quanti ne ha bisogno.

+0

Questo è un buon punto. In realtà sto usando i vettori in altri posti. Ma continuo a fare la maggior parte del mio lavoro in C, quindi tendo ad andare per quello che so quando aggiungo funzionalità ... – AShelly

0

Vorrei prendere in considerazione l'utilizzo di una std :: map. Può crescere con base e derivati ​​sia non curandosi del numero di parametri che gli altri usi. Le coppie chiave/valore sono probabilmente più facili da gestire per gli indici numerici, sebbene ciò dipenda chiaramente dall'applicazione.

0

Mi piacciono sia le risposte di Earwicker che quelle di Steve, a seconda di cosa è richiesto. Se molti di questi oggetti vengono creati e distrutti frequentemente, allora si desidera la quantità minima di allocazione di memoria possibile, e quindi Earwicker è superiore. Tuttavia, se si tratta di qualcosa che è solitamente "creato e raramente ri-prodotto", allora andrei con la risposta di Steve, poiché le mappe sono generalmente molto più facili da utilizzare e crescono dinamicamente secondo necessità, ma è probabilmente troppo sovraccarico se questo oggetto è qualcosa che viene fatto e distrutto molto.

2

Si potrebbe fare un parametro per il costruttore, come suggerito da altri, ma si potrebbe anche rendere Base una classe template, con le dimensioni come parametro. Ciò presenta molti vantaggi, ad esempio la rimozione della necessità dell'array da allocare nell'heap:

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; } 
}; 
Problemi correlati