Estoy tratando de emular un constructor. Estoy intentando hacer esto haciendo que una estructura principal tenga un puntero de función que devuelve un puntero a una estructura secundaria. Cualquier ayuda sería muy apreciada.
#include <stdio.h> #include "stdlib.h" typedef struct child_t { char *name; } Child; typedef struct parent_t { Child (*NewChild)(); } Parent; Child *NewChild() { Child *child = malloc(sizeof(Child)); child->name = "foo"; return child; } int main() { Parent parent; Child child = parent.NewChild(); }Parece que no has inicializado parent.NewChild . Intente establecer eso en el puntero de función antes de llamarlo, así: parent.NewChild = NewChild; .
Además, ¿no te falta el * en Child *child = parent.NewChild(); ?
Anexo: Por los comentarios, también hay un error/conflicto en la declaración de Parent : Su función miembro NewChild se declara para devolver un Child , mientras que el método gratuito NewChild devuelve un Child* . Por lo tanto, declare el puntero de la función miembro como Child * (*NewChild)(); .
creo que te refieres a lo siguiente
#include <stdio.h> #include <stdlib.h> typedef struct child_t { char *name; } Child; typedef struct parent_t { Child * ( *NewChild )( void ); } Parent; Child * NewChild( void ) { Child *child = malloc( sizeof( Child ) ); child->name = "foo"; return child; } int main( void ) { Parent parent = { NewChild }; Child *child = parent.NewChild(); puts( child->name ); free( child ); }La salida del programa es
fooEs decir, debe declarar la función correctamente. Su tipo de retorno debe ser un puntero. Entonces debe declarar el puntero de función correctamente en la definición de estructura
typedef struct parent_t { Child (*NewChild)(); ^^^^^^ } Parent;Y necesita inicializar el objeto de tipo Padre.
Parent parent = { NewChild };de lo contrario, tiene un valor indeterminado.
Veo los siguientes problemas en su código.
Función no coincidente y puntero de función
En Parent , ha definido NewChild como:
Child (*NewChild)(); Eso dice que NewChild es un puntero a una función que no toma argumentos y devuelve un objeto Child .
La función que has definido:
Child *NewChild() { ... No toma argumentos y devuelve un puntero a Child , no un objeto de Child .
Tendrás que decidir cuál necesita ser arreglado. Para corregir la función, haga que su retorno sea de tipo Child .
Child NewChild() { ... Child no inicializado del parent
Ha dejado el valor de parent.Child sin inicializar pero está tratando de usarlo.
Configuración del miembro de Child
Utiliza el siguiente código para establecer el name del child .
child->name = "foo"; Esto puede o no ser un problema dependiendo de cómo use child->name ya que child->name apunta a algunos datos globales en la memoria de solo lectura de la computadora. Será mejor hacer una copia de "foo" .
Aquí está mi sugerencia para actualizar su código:
Child NewChild() { Child child; // strdup is available on some platforms but it can // be implemented easily. child->name = strdup("foo"); return child; } int main() { Parent parent; parent.NewChild = NewChild; Child child = parent.NewChild(); }