Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   ¿ copia por valor de Matriz dinamica como lo hago? (https://www.clubdelphi.com/foros/showthread.php?t=70709)

NEG1414 06-11-2010 10:27:13

¿ copia por valor de Matriz dinamica como lo hago?
 
Buenas

He creado una Martriz dinamica de la forma

Código:

TClassPadre
 {
 
      Public::
 
      char Dat[10];
 
      typedef struct {char ** Dat;}TMatriz;
 
      TMatriz Matriz;     
 
  }

La Uso como tipo en clase Hija


Código:

ClassHija
{
   
      TMatriz::TClassPadre  Matz1
      TMatriz::TClassPadre  Matz2
}

Le asigno datos a MATZ1 :


Código:

ClassHija::AsigDatos
{
 
 Matz1.Dat=(char **)malloc(sizeof(char *)*NumDatos+1);
 
 for(int i=1;i<NumDatos+1;i++)
  {
      Matz1.Signo[i]=(char*)malloc(sizeof(char)*10;
      for(int b=1;b<10;b++)
        {
          Matz.Dato[i][b] =  'x'
        }
  }
}

Inicializo Matz2 con los datos de Matz1


Código:

ClassHija::DUDA
{
    Matz2 = Matz1;
}

Tal como lo he hecho al modifiar los Datos de Matz2 afecta a Matz1 (punteros)

Mi pregunta es:
Como puedo Hacer que Mtz2 se inicialice con los datos de Mtz1 y al modificar sus datos (Matriz Auxiliar) no afecte a los datos de Mtz1.
Si no es posible hay alguna otra forma...


Gracias

coso 06-11-2010 11:48:36

Hola,
tal como dices, estas asignando punteros, por lo que las dos variables (matz2 y matz1) en realidad comparten las mismas posiciones de memoria, y son en esencia la misma variable que la representan dos simbolos diferentes. Para copiar los datos, tendrias que usar las funciones de C para copiar, copiando asi los datos de unas posiciones de memoria en otras. Creo que era strcpy la funcion correcta para estas cosas. Espero que te sirva, un saludo.

NEG1414 07-11-2010 08:12:49

Gracias por contestar...

La utilizacion de strcpy es una opcion pero creo que la copia se realizaria caracter a caracter rrecorriendo toda la matriz, que para matrices de gran tamaño (millones) requiere un poco de tiempo. Desta forma tengo la opcion tambien

Código:

  typedef char TMatriz[15][15];

  TMatriz Matz1 = new TMatriz;
  TMatriz Matz2 = new TMatriz;


    Matz2[x][y] = (*Matz1) [x][y]

He estado indagando y creo que la unica solucion es crear una clase Matriz y en ella implemetar un constructor de copia que hace que con la asignacion = entre dos matrices de la clase realice una copia "real".

Gracias otra vez

coso 07-11-2010 11:34:47

hola, sigo pensando que te confundes, la mejor solución es usar strcpy en tu funcion de assign (lo que llamas "copia real"), ya que es la funcion estandar de C para copiar grandes bloques de memoria, y esta mas que optimizada desde hace mucho tiempo, aunque hay otras funciones en librerias especializadas. De todas maneras, sí es mas entendible copiar caracter por caracter en un bucle for. Dejo este post unicamente por si se relee, para que no hayan confusiones. Un saludo.

escafandra 07-11-2010 20:37:37

En realidad los dos hacéis referencia a dos cosas importantes.

1.- La implementación de un constructor copia y la sobrecarga del operador "=" permiten realizar cosas como esta:
Código:

TMatriz Matz1;
TMatriz Matz2;

Matz2 = Matz1;
TMatriz Matz3(Matz1);

En todos los casos Matz2 y Matz3 contendrán lo mismo que Matz1 pero serán "copias", no comparten el mismo espacio de memoria.

No es necesario crearlas con punteros como se exige en el caso de trabajar con la VCL.

2.- El código usado en el constructor copia o la sobrecarga del operador "=" debe realizar una copia real a nivel de memoria de una matriz en la otra. Bien con strcpy, memcpy o la API CopyMemory. Para el caso de strcpy decir que sólo es válido para cadenas estilo C (terminadas en nulo) pues encontrado el nulo termina la copia que es carácter a carácter.

Saludos.

NEG1414 10-11-2010 10:11:42

Buenas... Teniendo encuenta lo dicho anteriormente he implemetado una clase Matriz de la forma

Código:


 
class TMatriz
{
 
  private:
 
    **Matriz;
 
  public:
 
  TMatriz(int Nfilas,int NColumnas); // Constructor
 
  TMatriz (const TMatriz &m);  //Constructor de Copia
 
  const TMatriz &m operator = (const TMatriz &m) //Sobrecarga asignacion =
 
}
 
 
Tmatriz::Tmatriz(int Nfilas, Int NColumnas)
{
 
    Matriz = new char *[NColumnas]
 
  for (int i=0;i<NColumnas;i++)
    {
          Matriz[i] = new char [Numfilas];
    }
 
}



He intentado implementar la funcion constructor de copia (reservando memoria con memcpy) y la funcion sobrecarga asignacion y no lo consigo...me podeis ayudar

Gracias

escafandra 10-11-2010 18:29:26

Básicamente la cosa sería algo así:
Código:

class TMatriz
{
 
  private:

  char **Matriz;
  int Filas;
  int Columnas;

  public:
  TMatriz();
  TMatriz(int Nfilas, int NColumnas); // Constructor
  TMatriz (const TMatriz&);  //Constructor de Copia
 
  TMatriz &operator=(const TMatriz&);
};

// Constructor por defecto
TMatriz::TMatriz(): Filas(0), Columnas(0), Matriz(0)
{
}

TMatriz::TMatriz(int Nfilas, int NColumnas): Filas(Nfilas), Columnas(NColumnas),
Matriz(0)
{
  Matriz = new char *[NColumnas];
  for(int i=0; i<NColumnas; i++)
    Matriz[i] = new char [Nfilas];
}

// Constructor copia
TMatriz::TMatriz(const TMatriz& E): Filas(0), Columnas(0), Matriz(0)
{
  *this = E;
}

// Sobrecarga del operador asignación
TMatriz& TMatriz::operator=(const TMatriz &E)
{
  // Libero mamoria
  if(Matriz){
    for(int i=0; i<Columnas; i++) delete [] Matriz[i];
    delete [] Matriz;
  }

  // Copio la Matriz
        Columnas = E.Columnas;
        Filas  = E.Filas;
  Matriz = new char *[Columnas];
  for(int i=0; i<Columnas; i++){
    Matriz[i] = new char [Filas];
    CopyMemory(Matriz[i], E.Matriz[i], Filas);
  }
        return *this;
}

Un ejemplo de uso:
Código:

  TMatriz Mt1(10,10);
  TMatriz Mt2(Mt1);  // Con el constructor copia
  TMatriz Mt3 = Mt1;  // Asignando


Saludos.

escafandra 10-11-2010 19:04:22

No te olvides de implementar un destructor. ;)

Saludos.

NEG1414 11-11-2010 08:56:38

Muchisimas Gracias........ eres un Crack.

Tendre que seguir trabajando con el tema de los punteros, no acabo de entenderlos del todo

Gracias otra vez


La franja horaria es GMT +2. Ahora son las 14:48:51.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi