2008-11-26 9 views
10

Me preguntaba si es posible declarar una matriz (tamaño no conocido en este momento), como miembro privado de una clase y luego establecer el tamaño en el constructor de la clase. Por ejemplo:C++ declaración de matriz en un encabezado

class Test { 
int a[]; 
public: 
Test(int size); 
}; 

Test::Test(int size) { 
a[size]; // this is wrong, but what can i do here? 
} 

¿Es esto posible o debo usar matrices dinámicas? ¡Gracias!

Respuesta

13

n esto no es posible. Las declaraciones de matriz en los encabezados deben tener un valor de tamaño constante. De lo contrario, es imposible que las construcciones como "sizeof" funcionen correctamente. Deberá declarar la matriz como un tipo de puntero y usar new [] en el constructor. Ejemplo.

class Test { 
    int *a; 
public: 
    Test(int size) { 
     a = new int[size]; 
    } 
    ~Test() { delete [] a; } 
private: 
    Test(const Test& other); 
    Test& operator=(const Test& other); 
}; 
+0

Necesita agregar CopyConstructor y operador de asignación y llamar a la versión correcta od delete. O usa un vector –

+0

Drat. Normalmente llamo a otras personas por el mismo problema ... Lo arreglaré en breve – JaredPar

+0

Olvidó corregir la eliminación. Así que lo hice. –

3

En primer lugar, generalmente es mejor inicializar las cosas en la lista de inicialización del constructor, no en el cuerpo del constructor.

Solo puede inicializar una matriz con un límite predefinido si sabe que está vinculado en tiempo de compilación. En esta situación, necesitará asignar dinámicamente el espacio.

Recuerde que debe tener un destructor que elimine la matriz cuando se destruya el objeto o se produzca una pérdida de memoria.

17

respuesta corta: No (El tamaño de una matriz se define en tiempo de compilación solamente)
Respuesta larga:

Se puede utilizar un vector para lograr el mismo resultado:

class Test 
{ 
    std::vector<int> a; 
    public: 
     Test(std::size_t size): 
      a(size) 
     {} 
}; 
+0

Deseo que las personas agreguen comentarios al marcar las respuestas. Al menos has vuelto al 0 – JaredPar

+1

A los enemigos les encanta odiar anónimamente. Odio a los enemigos! Te doy un punto. –

+0

+1 Para una buena respuesta práctica, si alguien tiene un problema, explica por qué (para que podamos mostrarte que Martin tiene razón) – orip

0

No, esto no es posible. Debe usar una matriz dinámica como std::vector. C99 permite que una estructura tenga una matriz sin tamaño como el último miembro, pero incluso cuando hace esto, tiene que asignar la memoria manualmente, p. con malloc().

4

Como han señalado otras respuestas, el tamaño de una matriz se fija en tiempo de compilación. Sin embargo, mediante el uso de plantillas que se pueden parametrizar el tamaño en tiempo de compilación:

template <int N> class Test { 
    int a[N]; 
public: 
    Test() { } 
}; 

Test<5> test; 
Test<40> biggertest; 

Esta técnica no le permite calcular el tamaño en el plazo tiempo (como la solución dinámica std::vector hace), pero dependiendo de sus necesidades esto puede ser suficiente

+0

Eso funciona, pero cada versión de Test es ahora una clase diferente. Por lo tanto, no hay amistad implícita (por lo tanto, no accesos para copiar, etc.) –

+0

No es que pueda copiar una prueba <2> de todos modos, no encajaría. Tampoco polimorfismo: la prueba <1> y la prueba <2> son tipos incompatibles, por lo que cada función que los maneja h como para ser templado también –

+0

sin preocupaciones. él todavía puede moldear el operador = y el cctor. –

0

De lo que está hablando no es posible. Las clases siempre tienen un tamaño constante. Puede hacer que su clase use un puntero a una matriz dinámicamente asignada o puede usar std :: vector.

2

Ver solución de Martin (utilizar std::vector), y recuerda que, incluso si se necesita pasar un buffer para una API C std::vector le permite hacerlo pasando &vec[0]:

std::vector<char> vec(10); 
memset(&vec[0], 0, vec.size()); 

Está garantizado para trabajar, pero sólo si el vector no está vacío (C++ peculiaridades, < suspiro>).

+0

Utilizo mucho el truco & vec [0], aunque el memset() en este caso es innecesario ya que el vec ya se habría inicializado en todos los ceros. –

+0

memset fue solo un ejemplo, pero tienes razón :) – orip

Cuestiones relacionadas