2009-04-15 8 views
13

En el código siguiente me gustaría que la matriz se definiera como una matriz de tamaño x cuando se llama al constructor de la clase. ¿Cómo puedo hacer eso?Determinar el tamaño de la matriz en el inicializador del constructor

class Class 
{ 
public: 
    int array[]; 
    Class(int x) : ??? { } 
} 
+1

I Si planea usar C++ regularmente, le recomiendo que se familiarice con la biblioteca de plantillas estándar. Hace que trabajar con colecciones de datos * mucho * sea más fácil. – Brian

+1

Como un lado, los vectores hacen que sea relativamente fácil trabajar con la matriz sin saber el tamaño por adelantado. No es necesario saber el tamaño por adelantado; puede agregar elementos al final de un vector en tiempo (amortizado) O (1) de todos modos usando push_back. – Brian

+0

Usar vectores trae problemas nuevos, ya que la clase que trato de vectorizar ha protegido a los "nuevos" operadores. Pero eso no fue lo que pedí, por lo tanto, no importa. – zaratustra

Respuesta

17

No se puede inicializar el tamaño de una matriz con una dimensión no const que no se puede calcular en tiempo de compilación (al menos no en C++ estándar actual, AFAIK).

Recomiendo usar std::vector<int> en lugar de una matriz. Proporciona una sintaxis tipo array para la mayoría de las operaciones.

+0

¿Cómo sería la sintaxis para usar un vector en esa situación? – zaratustra

+2

vector < int > matriz; Clase (x): matriz (x) {}; – DevSolar

1

En lugar de utilizar un conjunto sin formato, ¿por qué no utilizar un vector en su lugar.

class SomeType { 
    vector<int> v; 
    SomeType(size_t x): v(x) {} 
}; 

El uso de un vector le dará la protección automática de fugas en la cara de una excepción y muchos otros beneficios a través de una gama prima.

+0

¿Quiere decir "Usar * un vector * le dará protección contra fugas automática"? :) – mkb

+0

@mkb, eso es dos veces hoy. He hecho comentarios fundamentalmente estúpidos. Debe beber más café para despertarse antes de que empiece a publicar;) – JaredPar

11

utilizar el nuevo operador:

class Class 
{ 
    int* array; 
    Class(int x) : array(new int[x]) {}; 
}; 
+3

No se olvide de llamar a eliminar [] en el constructor si usa este código. – Brian

+7

Si lo hace, también necesitará un constructor de copia, un operador de asignación y un destructor. Usar un std :: vector te da exactamente la misma funcionalidad pero no requiere ninguno de estos. –

+0

+1 Esto en realidad responde a la pregunta del OP al inicializar el tamaño de una matriz, aunque en realidad está reemplazando 'int * array' que no es una matriz, con la lista en el constructor. @ (anon) además de un constructor de copia, un operador de asignación y un destructor, esto realmente responde a la pregunta. –

0

No puede hacerlo en C++ - utilizar un std :: vector en su lugar:

#include <vector> 

struct A { 
    std::vector <int> vec; 
    A(int size) : vec(size) { 
    } 
}; 
0

declara la matriz como un puntero. Puede inicializarlo en la lista de inicializadores más adelante a través de nuevo.

Es mejor usar vectores de tamaño desconocido.

Es posible que desee mirar this question también en matrices de longitud variable.

+0

es mejor usar el vector para el tamaño conocido también –

+0

tiene que estar de acuerdo con esa idea – Shree

+0

MALA. Hacer la gestión de la memoria en un puntero que actúa como una matriz no es trivial en presencia de excepciones. Use std :: vector o std :: tr1 :: array. –

3

No creo que se pueda hacer. Al menos no de la manera que quieres. No puede crear una matriz de tamaño estático (matriz []) cuando el tamaño proviene de información dinámica (x).

Tendrá que almacenar un puntero-a-int, y el tamaño, y sobrecargar el constructor de copias, el operador de asignación y el destructor para manejarlo, o usar std :: vector.

class Class 
{ 
    ::std::vector<int> array; 
    Class(int x) : array(x) { } 
}; 
0

dos opciones:

uso std :: vector. Esto permite un nuevo tamaño fácil de la matriz.
Utilice std :: tr1 :: array. Esto tiene un tamaño estático.

Ambos pueden inicializarse correctamente en la lista de inicializadores de constructores.

4

¿No entiendes que no es necesario usar vectores, si uno quiere usar arreglos, es una cuestión de eficiencia, por ej. menos espacio, no hay tiempo de copia (en tal caso, si se maneja adecuadamente, ni siquiera es necesario eliminar la matriz dentro de un destructor), etc., por los motivos que uno tenga.

la respuesta correcta es: (citado)

class Class 
{ 
    int* array; 
    Class(int x) : array(new int[x]) {}; 
}; 

No trate de forzar a que se debe usar alternativas no óptimas o tendrá que ser programadores inexpertos confusas

3

Lo siento por necroing este viejo hilo. En realidad, hay una manera de averiguar el tamaño de la matriz en tiempo de compilación.Es algo parecido a esto:

#include <cstdlib> 

template<typename T> 
    class Class 
    { 
     T* _Buffer; 

     public: 
     template<size_t SIZE> 
      Class(T (&static_array)[SIZE]) 
      { 
       _Buffer = (T*)malloc(sizeof(T) * SIZE); 

       memcpy(_Buffer, static_array, sizeof(T) * SIZE); 
      } 

      ~Class() 
      { 
       if(_Buffer) 
       { 
        free(_Buffer); 
        _Buffer = NULL; 
       } 
      } 
    }; 

int main() 
{ 
    int int_array[32]; 
    Class<int> c = Class<int>(int_array); 

    return 0; 
} 

Alternativamente, si no le gusta a malloc/nueva, entonces usted puede crear un tamaño de clase de plantilla en su lugar. Sin embargo, realmente no lo recomendaría y la sintaxis es bastante fea.

#include <cstdio> 

template<typename T, size_t SIZE> 
    class Class 
    { 
     private: 
      T _Array[sz]; 
     public: 
      Class(T (&static_array)[SIZE]) 
      { 
       memcpy(_Array, static_array, sizeof(T) * SIZE); 
      } 
    }; 

int main() 
{ 
    char int_array[32]; 
    Class<char, sizeof(int_array)> c = Class<char, sizeof(int_array)>(int_array); 
    return 0; 
} 

De todas formas, espero que esto era útil :)

+2

¿Es usted un asistente? – zaratustra

+0

En C++ 11, un método superior para determinar el tamaño de una matriz incorporada es usar una función de plantilla constexpr. Por ejemplo: plantilla constexpr std :: size_t size (const T (& array) [N]) { return N; } – Ricky65

25

Usted gente tienen de manera excesivamente complicada esto. Por supuesto, puedes hacer esto en C++. Está bien para él usar una matriz normal para la eficiencia. Un vector solo tiene sentido si no conoce el tamaño final de la matriz antes de tiempo, es decir, necesita crecer con el tiempo.

Si se puede saber el tamaño de la matriz de un nivel superior de la cadena, una clase de plantilla es la más fácil, porque no hay asignación dinámica y no hay posibilidad de pérdidas de memoria:

template < int ARRAY_LEN > // you can even set to a default value here of C++'11 

class MyClass 
    { 
    int array[ARRAY_LEN]; // Don't need to alloc or dealloc in structure! Works like you imagine! 
    } 

// Then you set the length of each object where you declare the object, e.g. 

MyClass<1024> instance; // But only works for constant values, i.e. known to compiler 

Si usted no puede saber la longitud en el lugar donde declaras el objeto, o si deseas reutilizar el mismo objeto con diferentes longitudes, o debes aceptar una longitud desconocida, entonces debes asignarlo en tu constructor y liberarlo en tu destructor ... (y en teoría siempre verifique para asegurarse de que funcionó ...)

class MyClass 
    { 
    int *array; 

    MyClass(int len) { array = calloc(sizeof(int), len); assert(array); } 
    ~MyClass() { free(array); array = NULL; } // DON'T FORGET TO FREE UP SPACE! 
    } 
Cuestiones relacionadas