2009-03-27 8 views
5

Tengo una jerarquía de clases. La clase base usa algunos parámetros de ajuste que se pueden cargar desde el archivo (y se pueden cargar durante el tiempo de ejecución). Cada clase derivada puede agregar algunos parámetros adicionales. Estoy buscando una manera de asignar una matriz de parámetros del tamaño correcto en el constructor base, de modo que no tenga que desasignar y reasignar en la clase derivada. Me esperaba algo así, pero no está funcionando (parámetros siempre tiene 2 elementos):¿Cómo asignar una matriz en el constructor base con el tamaño basado en la clase derivada?

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; 

que he visto this question, pero la solución no hace el trabajo bastante para mí. También probé haciendo parámetros una matriz regular en cada clase:

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

pero que hace derivados tienen 2 matrices independientes.

¿Alguna idea?

Respuesta

5

¿Por qué no pasar el tamaño de matriz requerido como un parámetro en el constructor de la clase base?

(La razón por la función virtual no llama a la clase derivada es porque así es como funcionan las funciones virtuales C++;. Conceptualmente, hasta que el constructor de la clase derivada se completa, el tipo del objeto sigue siendo la clase base)

+0

¿Por qué no? ¡Muy obvio! A veces me limito demasiado a los detalles ... Gracias por la explicación de por qué. – AShelly

+0

¡Ningún problema, le sucede a todos! –

2

¿Qué hay de hacer que el tamaño sea un parámetro?

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

¿Por qué utilizar una matriz? El std :: vector le permitirá usar tantos params como sea necesario en la clase derivada, con la base sin saber (o preocuparse) cuántos necesita.

+0

Ese es un buen punto. En realidad estoy usando vectores en otros lugares. Pero sigo haciendo la mayor parte de mi trabajo en C, así que tiendo a ir por lo que sé cuando estoy agregando características ... – AShelly

0

Considero el uso de un estándar :: mapa. Puede crecer con base y derivarse sin preocuparse por la cantidad de parámetros que usa el otro. Es probable que los pares clave/valor sean más fáciles de administrar que los índices numéricos, aunque eso depende claramente de la aplicación.

0

Me gustan las respuestas de Earwicker y Steve, según lo que se requiera. Si hay muchos de estos objetos creados y destruidos con frecuencia, entonces usted quiere la cantidad mínima de asignación de memoria posible, y por lo tanto Earwicker es superior. Sin embargo, si esto es algo que normalmente se "crea y rara vez se vuelve a hacer", me gustaría ir con la respuesta de Steve, ya que los mapas son generalmente mucho más fáciles de trabajar y crecer dinámicamente según sea necesario, pero probablemente sea demasiado sobrecargado si este objeto es algo que se hace y se destruye mucho.

2

Puede hacer que sea un parámetro para el constructor, como lo sugirieron otros, pero también podría hacer que Base sea una clase de plantilla, con el tamaño como parámetro. Esto tiene muchas ventajas, como eliminar la necesidad de que la matriz se asigne en el montón:

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; } 
}; 
Cuestiones relacionadas