Estoy intentando crear una clase que tenga un miembro privado que sea una matriz. No sé el tamaño de la matriz y no lo haré hasta que el valor pase al constructor. ¿Cuál es la mejor manera de definir el constructor de clase así como la definición en el archivo .h para permitir este tamaño variable de la matriz?Matriz como miembro privado de la clase
Respuesta
Si desea una matriz de estilo C "real", debe agregar un miembro privado de puntero a su clase y asignar dinámicamente la memoria para ello en el constructor (con new). Obviamente, no debes olvidar liberarlo en el destructor.
class YourClass
{
private:
int * array;
size_t size;
// Private copy constructor operator to block copying of the object, see later
// C++03:
YourClass(const YourClass &); // no definition
// C++11:
YourClass(const YourClass&) = delete;
public:
YourClass(size_t Size) : array(new int[Size]), size(Size)
{
// do extra init stuff here
};
~YourClass()
{
delete [] array;
}
};
para hacer este trabajo más fácil, puede considerar utilizar un puntero inteligente (por ejemplo, un boost::scoped_array en C++ 03, o simplemente std::unique_ptr
en C++ 11), que puede inicializar utilizando el inicializador lista antes del constructor o simplemente en el constructor.
class YourClass
{
private:
boost::scoped_array<int> array; // or in C++11 std::unique_ptr<int[]> array;
size_t size;
public:
YourClass(size_t Size) : array(new int[Size]), size(Size)
{
// do extra init stuff here
}
// No need for a destructor, the scoped_array does the magic
};
Tanto estas soluciones producen objetos noncopyable (no se especificó si tuvieran que ser copiable y su copia semántica); si la clase no tiene que ser copiada (lo que sucede la mayoría de las veces), ambas están correctas, y el compilador generará un error si intentas copiar/asignar una clase a otra, en el primer caso porque la copia predeterminada el constructor se ha sobrecargado con uno privado (o un plano eliminado en C++ 11), en el segundo caso porque boost::scoped_array
y std::unique_ptr
no se pueden copiar.
Si, por el contrario, desea tener objetos copiables, debe decidir si desea crear una copia que comparta la matriz (por lo tanto, solo una copia de puntero) o si desea crear una nueva matriz separada para el otro objeto.
En el primer caso, debe tener mucho cuidado antes de liberar la memoria asignada, ya que otros objetos pueden estar usándola; un contador de referencia es la solución más común. Puede recibir ayuda en esto por boost::shared_array (o std::shared_ptr
en C++ 11), lo que hace que todo el seguimiento funcione automáticamente para usted.
Si, por el contrario, desea hacer una "copia profunda", tendrá que asignar la nueva memoria y copiar todos los objetos de la matriz de origen a la matriz de destino. Esto no es completamente trivial para hacer correctamente, y generalmente se realiza a través del "copy and swap idiom".
Aún así, la solución más simple es usar un std::vector
como miembro privado: manejaría todas las cosas de asignación/desasignación por sí mismo, construyéndose/destruyéndose correctamente cuando se construye/destruye el objeto de su clase. Además, implementa la semántica de copia profunda de la caja. Si necesita hacer que las personas que llaman accedan al vector de solo lectura, entonces, puede escribir un getter que devuelva una referencia const_iterator
o const
al objeto vector
.
El uso de std :: vector es la mejor opción. Si alguna vez necesita pasarlo a una función que espera un puntero a una matriz (como la GSL a menudo lo hace), aún puede pasar &vec[0]
...
- 1. C# serializar miembro privado de la clase
- 2. Clase de miembro estático: ¿declara clase privada y miembro de clase paquete privado?
- 3. miembro privado accesible desde otras instancias de la misma clase
- 4. decltype (función) como miembro de la clase
- 5. boost mutex error extraño con miembro privado
- 6. Referencia como inicialización de miembro de clase
- 7. ¿Cómo heredar un miembro privado en JavaScript?
- 8. PHP5. Dos formas de declarar una matriz como miembro de la clase
- 9. ¿Se llama inmediatamente al constructor para una matriz de objetos como miembro de la clase?
- 10. miembro privado de Javascript en el prototipo
- 11. miembro de referencia como miembros de la clase
- 12. ¿Matriz como propiedad de la clase?
- 13. incluyendo clase como miembro en struct
- 14. ¿Puede una clase C++ incluirse como miembro?
- 15. ¿Hay alguna forma de que pueda acceder a la variable de miembro privado de una clase?
- 16. ¿Por qué se puede cambiar la variable de miembro privado por instancia de clase?
- 17. C++ - Inicializando un mapa estático como miembro de clase privada
- 18. Puzzle - exposición de una sub-miembro público de miembro privado con el tipo de encargo
- 19. ¿Por qué esta función amiga no puede acceder a un miembro privado de la clase?
- 20. 'QObject :: QObject' no puede miembro privado de acceso declarado en la clase 'QObject'
- 21. ¿Por qué hacer que un miembro privado de la clase interna sea público en Java?
- 22. Clases abstractas, ¿por qué no podemos declarar val privado y miembro de la clase var?
- 23. Puntero como miembro o Referencia como miembro
- 24. C# anular miembro público y hacerlo privado
- 25. cómo devolver adecuadamente una matriz (miembro de la clase) en C++?
- 26. ¿Cuál es la diferencia entre encapsular a un miembro privado como una propiedad y definir una propiedad sin un miembro privado?
- 27. ¿Cómo inicializar una matriz miembro de clase en el constructor?
- 28. C++ miembro función de acceso privado variable estática?
- 29. iOS 4 - Uso de bloques como miembro de una clase
- 30. ¿Por qué el acceso de reflejo es miembro protegido/privado de clase en C#?
Para las matrices, asegúrese de utilizar ' scoped_array', not 'scoped_ptr'. –
Corregido, gracias. Siempre obtengo el delete [] correcto, pero a veces me olvidé de las versiones de matriz de los punteros inteligentes. –
El único truco es si YourClass se puede copiar, porque scoped_ * no se puede copiar en el impulso. Eso no está especificado en la pregunta de todos modos, así que +1 de todos modos. – Skurmedel