https://foro.gambas-es.org/viewtopic.php?f=1&t=7983
-----------------------------------
tercoIDE
Thursday, 23 April 2020, 16:42

Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
El problema:
      Obtener un New objeto que sea igual que el referenciado, tanto en su clase como en todas sus variables y propiedades. O sea, un clon pero en otra posicion de memoria.

[code linenumbers=false syntax=gambas]
Public c1 as New Clase1
Public c2 as New Clase2                   ' Son todas distintas
Public c3 as New Clase3
Public c4 as New Clase4


Public Sub ClonMe(original as Object) as Object

' un nuevo objeto igual al original
????? 

End[/code]


-----------------------------------
jsbsan
Thursday, 23 April 2020, 19:16

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
tercoIDE:
Mirate esto: http://sologambas.blogspot.com/2014/09/poo-en-gambas3-copiar-objetos.html

A ver si te sirve...

Saludos

Julio


-----------------------------------
vuott
Thursday, 23 April 2020, 19:31

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="jsbsan" post="48014"]tercoIDE:
Mirate esto: http://sologambas.blogspot.com/2014/09/poo-en-gambas3-copiar-objetos.html

A ver si te sirve...[/quote]
Yo supongo que no: ...[i]tercoIDE[/i] en estos días está de humor para refinamientos "excesivos".    :lol:


-----------------------------------
vuott
Thursday, 23 April 2020, 19:42

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="tercoIDE" post="48013"]El problema:
      Obtener un New objeto que sea igual que el referenciado, tanto en su clase como en todas sus variables y propiedades. O sea, un clon pero en otra posicion de memoria.

[code linenumbers=false syntax=gambas]
Public c1 as New Clase1
Public c2 as New Clase2                   ' Son todas distintas
Public c3 as New Clase3
Public c4 as New Clase4


Public Sub ClonMe(original as Object) as Object

' un nuevo objeto igual al original
????? 

End[/code][/quote]
Me parece que tú quieres obtener, crear un Objeto "c5" pero sin la sintaxis "[i]As New .....[/i]", sino obteniéndolo del Objeto pasado a la función, como modelo, como [u]base[/u].

De todos modos yo te respondo con otra pregunta: ¿desde el punto de vista del [u]bajo nivel[/u], qué significa crear un [i]Objeto[/i], una [i]instancia[/i] de una Clase?


-----------------------------------
tercoIDE
Thursday, 23 April 2020, 20:29

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="jsbsan" post="48014"]tercoIDE:
Mirate esto: http://sologambas.blogspot.com/2014/09/poo-en-gambas3-copiar-objetos.html

A ver si te sirve...

Saludos

Julio[/quote]


No funciono porque la clase tiene un array de otro clase menor


[code linenumbers=false syntax=gambas]' SAVE from this
Public P As New Punto[]                     ' acumulador de puntos
Public Level As Float                       ' from 0 to 1

' For future use in CAD implementation
Public Layer As Integer                      ' Capa o Layer
Public Group As Integer                     ' Para tener la posibilidade de juntar cosas en un grupo
Public _Color As Integer                     ' Para darle un color distinto al del layer
Public LineType As Integer                  
Public LineWidth As Integer                  
[/code]

La variable P es un array de clase Punto. La rutina que me pasaste no puede procesar eso.


-----------------------------------
tercoIDE
Thursday, 23 April 2020, 20:33

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="vuott" post="48016"][
Me parece que tú quieres obtener, crear un Objeto "c5" pero sin la sintaxis "[i]As New .....[/i]", sino obteniéndolo del Objeto pasado a la función, como modelo, como [u]base[/u].

De todos modos yo te respondo con otra pregunta: ¿desde el punto de vista del [u]bajo nivel[/u], qué significa crear un [i]Objeto[/i], una [i]instancia[/i] de una Clase?[/quote]

Quiero crear una nueva instancia de un objeto del cual no conozco la clase y copiar todo el contenido.

No se como trabaja internamente gambas, pero tal vez un objeto sea una porcion de memoria con datos interpretables por GBX y tal vez, solo tal vez pueda ser copiado como eso, una porcion de memoria y asignada a un puntero de un objeto nuevo...tal vez...habria que meter la cabeza en el agujero como tu avestruz


-----------------------------------
tercoIDE
Thursday, 23 April 2020, 21:22

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="tercoIDE" post="48017"]


[code linenumbers=false syntax=gambas]' SAVE from this
Public P As New Punto[]                     ' acumulador de puntos
Public Level As Float                       ' from 0 to 1

' For future use in CAD implementation
Public Layer As Integer                      ' Capa o Layer
Public Group As Integer                     ' Para tener la posibilidade de juntar cosas en un grupo
Public _Color As Integer                     ' Para darle un color distinto al del layer
Public LineType As Integer                  
Public LineWidth As Integer                  
[/code]

La variable P es un array de clase Punto. La rutina que me pasaste no puede procesar eso.[/quote]


Este codigo funciona para mi caso particular. Pero tengo que meter los puntos a mano.
Estaria bien tener un codigo universal.

[code linenumbers=false syntax=gambas]
Public Sub Clone(hObjeto As Object) As Object
    Dim SinPuntos As Object
    
    SinPuntos = CopyElementObject(hObjeto) 
    
    ' ahora meto los puntos a mano
    Dim p2 As Punto
        
    For Each p2 In hObjeto.p
        SinPuntos.P.add(puntos.Add(p2.x, p2.z, p2.Level))
    Next
    
    SinPuntos.finish()
    
    
    Return SinPuntos ' pero ahora tiene :)

End 


Public Sub CopyElementObject(hObjeto As Object) As Object
 
  Dim hNewMe As Object = Object.New(Object.Type(hObjeto)) 'se genera un objeto de la mismo tipo  que nos pasan
  Dim s As String    'variable utilizada para almacenar el valor de hclass.symbols
  Dim hclass As Class = Object.Class(hObjeto) 'contiene el valor de la clase del objeto
  Dim hChild As Object
 
  Dim nuevoObjeto As Object
  Dim caso As Integer 'tipo de dato de la propiedad del objeto
 
  Dim contador, a As Integer 'para usarlo en bucle si son arrays
  Dim arrayPosible As Object
    
            'Inicio de la copia de las propiedades....
            For Each s In hclass.Symbols
              If s = "Chlidren" Then Continue
                If Not hclass[s].ReadOnly Then  ' esto se cumple cuando llego a P[0]
                  caso = TypeOf(Object.GetProperty(hObjeto, s))
                 
                        Select Case caso
                          Case gb.Object
                            'la propiedad es un objeto, vuelvo a llamar a la funcion para que me extraiga los valores y no las referencias
                            nuevoObjeto = CopyElementObject(Object.GetProperty(hObjeto, s))
                            Object.SetProperty(hNewMe, s, nuevoObjeto)  
                           
                            Try contador = Object.GetProperty(hObjeto, s).count
                            If Error Then
                              'no es un array
                             
                            Else
                              For a = 0 To contador - 1
                                nuevoObjeto.add(Object.GetProperty(hObjeto, s)[a])
                              Next
                            Endif
                           
                          Default
                            'la propiedad no es un objeto, copio el valor
                            Object.SetProperty(hNewMe, s, Object.GetProperty(hObjeto, s))        
                        End Select
                 
                Endif
             
            Next

  Return hNewMe
 
End[/code]


-----------------------------------
tincho
Thursday, 23 April 2020, 22:31

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="tercoIDE" post="48013"]El problema:
      Obtener un New objeto que sea igual que el referenciado, tanto en su clase como en todas sus variables y propiedades. O sea, un clon pero en otra posicion de memoria.
[/quote]
Los objetos collection se pueden copiar. 
Por ejemplo.
[code linenumbers=false syntax=gambas]
Public Sub Form_Open()

  Dim c1 As New Collection
  Dim c2 As New Collection
  Dim v As Variant

  c1.Add("texto1", "clave1")
  c1.Add("texto2", "clave2")

  c2 = c1.Copy() 'Intercambiendo esta linea por la siguiente se ve el efecto 'Copy' y el efecto '='
  'c2 = c1

  c2.Add("texto3", "clave3")

  Print "Collection 1 -----------"
  For Each v In c1
    Print c1.Key & ":" & v
  Next
  Print "\n"
  Print "Collection 2 -----------"
  For Each v In c2
    Print c2.Key & ":" & v
  Next

End
[/code]
Saludos.


-----------------------------------
tincho
Thursday, 23 April 2020, 22:35

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
Esta función podria servir
[code linenumbers=false syntax=gambas]
Public Function MCopy(obj As Object) As Object
  
  Dim oky As Object
  
  oky = obj.Copy()
  
  Return oky
  
End
[/code]
Saludos.


-----------------------------------
vuott
Thursday, 23 April 2020, 23:07

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="tercoIDE" post="48018"]... un objeto sea una porcion de memoria con datos interpretables por GBX [/quote]
Exactamente, y esto lo hace el Constructor "[b][i]New[/i][/b]".
[b][i]New[/i][/b] construye las Estructuras y las sub-estructuras necesarias y previstas para dar vida al Objeto deseado, asignando la necesaria memoria.



[quote user="tercoIDE" post="48019"]Estaria bien tener un codigo universal.[/quote]
Yo propondría el siguiente ejemplo:  :| 

[u]Modulo principal[/u]
[code linenumbers=false syntax=gambas]Public Sub Main()

  Dim cl As New Class1
  Dim clone As Object
  Dim b As Byte

  clone = ClonMe(cl)

' Verificación:
  Print "Objeto \e[1mcl\e[0m = "; cl, "Objeto \e[1mclone\e[0m = "; clone
  Print "\nSus recursos:"
  For b = 0 To Object.Class(cl).Symbols.Max
    Print "Objeto cl = "; Object.Class(cl).Symbols[b]; "      "; "Objeto clone = "; Object.Class(clone).Symbols[b]
  Next

  Print clone.Adde(500)
  Print clone.Subtrahe(500)
  
End


Public Function ClonMe(original As Object) As Object

  Dim novum As Object

' Un nuevo objeto igual al original (por supuesto hace falta usar el Metodo "New"):
   novum = Object.Class(original).New(Null)

   Return novum

End[/code]


[u]Clase secundaria:  Class1.class[/u]
[code linenumbers=false syntax=gambas]Public Const VAR As Integer = 100


Public Function Adde(i As Integer) As Integer
  
  Return i + VAR
  
End


Public Function Subtrahe(i As Integer) As Integer
  
  Return i - VAR
  
End[/code]


-----------------------------------
tercoIDE
Friday, 24 April 2020, 03:33

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="vuott" post="48022"]
[code linenumbers=false syntax=gambas]' Un nuevo objeto igual al original (por supuesto hace falta usar la palabra llave "New"):
   novum = Object.Class(original).New(Null)[/code]
[/quote]

El problema es que cuando la clase tiene un array de otra clase como variable, esa linea no la reconstruye correctamente. 
La solucion propuesta por Tincho tampoco. Pero el equivocado era yo que estaba escribiendo codigo nada optimizado.

Finalmente opte por reescribir  buena parte de mi codigo poniendo Embedded Arrays en las clases, que no son lo mas recomendable, pero son mas rapidos de acceder y los mas importante, se eliminan con el objeto.


-----------------------------------
tercoIDE
Friday, 24 April 2020, 14:17

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
Lo solucione poniendo en cada clase estas lineas, pero no es lo que queria:

[code linenumbers=false syntax=gambas]' dentro de la clase
Public Sub Clon() as clsClase

   Return New clsClase

End
[/code]


-----------------------------------
Shell
Thursday, 02 July 2020, 21:21

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
Una cuestión.  :roll: 

Si sabemos la dirección de memoria que se encuentra el objeto y su tamaño:

¿ No podemos copiar el contenido de los bytes que se encuentra en esa dirección a otra nueva dirección y con eso crear un nuevo objeto en la memoria ?.

¿ Es posible luego la conversión de puntero y datos a objeto ?.


Saludos


-----------------------------------
tercoIDE
Thursday, 02 July 2020, 22:50

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="Shell" post="49007"]Una cuestión.  :roll: 

Si sabemos la dirección de memoria que se encuentra el objeto y su tamaño:

¿ No podemos copiar el contenido de los bytes que se encuentra en esa dirección a otra nueva dirección y con eso crear un nuevo objeto en la memoria ?.

¿ Es posible luego la conversión de puntero y datos a objeto ?.


Saludos[/quote]

eso lo planteo Vuott, pero no sirve porque si tiene arrays dinamicos estan en otro lado

pero abandone usar objetos y clases de esa forma porque la perfomance era mala, segun recomendacion de Benoit


-----------------------------------
vuott
Friday, 03 July 2020, 14:45

Re: Clases: Como Clonar Un Object De Una Clase Que No Conocemos?
-----------------------------------
[quote user="tercoIDE" post="49009"]eso lo planteo Vuott, pero no sirve porque si tiene arrays dinamicos estan en otro lado[/quote]

    :?:


