2011-10-31 21 views
14

Tengo un programa en C++:C++. Error: void no es un tipo puntero a objeto

struct arguments 
{ 
    int a, b, c; 
    arguments(): a(3), b(6), c(9) {} 
}; 

class test_class{ 
    public: 

    void *member_func(void *args){ 
     arguments vars = (arguments *) (*args); //error: void is not a 
               //pointer-to-object type 

     std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n"; 
    } 
}; 

En compilar arroja un error:

error: ‘void*’ is not a pointer-to-object type 

Puede alguien explicar lo que estoy haciendo mal a producir este error?

+0

Sí, la hay. ¿Has intentado darle a 'args' otro tipo de datos? – Blender

+2

No tiene ningún "tipo abstracto" (supongo que quiere decir clases base abstractas) en este ejemplo. Probablemente quiera decir '* (arguments *) args', que convierte' args' de 'void *' a 'arguments *', _then_ lo hace de referencia. Tu código actual intenta desreferenciar un 'void *' (que es ilegal), luego convierte el valor desreferenciado a 'arguments *', que seguramente no es lo que pretendías. –

+0

@Chris Sí, eso es lo que estaba tratando de hacer, gracias por la aclaración. Por cierto, pensé que las estructuras y las clases se consideraban tipos abstractos, por ejemplo. int, float no son abstractos. –

Respuesta

17

Estás eliminación de referencias a la void * antes de depositarlo a un tipo concreto. Es necesario hacerlo al revés:

arguments vars = *(arguments *) (args); 

Esta orden es importante, ya que el compilador no sabe cómo aplicar a *args (que es un void * y no se puede eliminan las referencias). Su (arguments *) le dice qué hacer, pero es demasiado tarde, porque la desreferencia ya se ha producido.

+1

Pero por favor usa 'static_cast' aquí - obtendrías un mejor mensaje de error de esa manera ... –

+0

@Billy ¿qué hace' static_cast'? –

+1

@Matt: Lo mismo que un lanzamiento de estilo C, excepto más limitado. 'static_cast' no permite la eliminación de' const', la reinterpretación de un tipo de puntero y algunas otras cosas desagradables. En términos generales, cualquier cosa que 'static_cast's funcione en plataformas/arquitecturas. Consulte la sección 5.2.9 del estándar C++ para obtener más detalles (suponiendo C++ 03) –

3

Tiene el * en el lugar equivocado. Por lo tanto, intenta desreferenciar el void*. Tal vez puedas probar:

arguments vars = *(arguments *) (args); 
std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n"; 

Alternativamente, usted puede hacer esto: (que también evita el constructor de copia - como se ha mencionado en los comentarios)

arguments *vars = (arguments *) (args); 
std::cout << "\n" << vars->a << "\t" << vars->b << "\t" << vars->c << "\n"; 
+0

Dejarlo como un puntero es probablemente mejor, ya que evita un constructor de copia. Sin embargo, el OP debería hacer que el puntero (tanto 'arguments *' como 'void *') 'const'. –

0

* args significa "el objeto (valor) args apunta a". Por lo tanto, no se puede convertir como puntero a objeto (argumento). Es por eso que está dando error

4

sencillísimas ejemplo para reproducir el error anterior:

#include <iostream> 
using namespace std; 
int main() { 
    int myint = 9;    //good 
    void *pointer_to_void;  //good 
    pointer_to_void = &myint; //good 

    cout << *pointer_to_void; //error: 'void*' is not a pointer-to-object type 
} 

El código anterior es incorrecta, ya que está tratando de eliminar la referencia de un puntero a un vacío. Eso no está permitido.

Ahora ejecute el siguiente código a continuación, si comprende por qué se ejecuta el siguiente código y el código anterior no, estará mejor equipado para comprender lo que sucede bajo el capó.

#include <iostream> 
using namespace std; 
int main() { 
    int myint = 9; 
    void *pointer_to_void; 
    int *pointer_to_int; 
    pointer_to_void = &myint; 
    pointer_to_int = (int *) pointer_to_void; 

    cout << *pointer_to_int; //prints '9' 
    return 0; 
} 
0

El problema como bdonlan dicho es "dereferencing void* antes de emitir".

creo que este ejemplo podría ayudar a:

#include <iostream> 

using namespace std; 

int main() 
{ 



    void *sad; 
    int s = 23; 
    float d = 5.8; 

    sad = &s; 
    cout << *(int*) sad;//outputs 23//wrong: cout << *sad ;//wrong: cout << (int*) *sad; 



    sad = &d; 
    cout << *(float *) sad;//outputs 5.8//wrong: cout << *sad ;//wrong: cout << (float*) *sad; 

    return 0; 
} 
Cuestiones relacionadas