J'ai un programme C++:
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";
}
};
Lors de la compilation, une erreur est générée:
error: ‘void*’ is not a pointer-to-object type
Quelqu'un peut-il expliquer ce que je fais mal pour produire cette erreur?
Vous déréférenciez le void *
avant de le transformer en un type concret. Vous devez le faire dans l'autre sens:
arguments vars = *(arguments *) (args);
Cet ordre est important, car le compilateur ne sait pas comment appliquer *
à args
(qui est un void *
et ne peut pas être déréférencé). Votre (arguments *)
lui indique quoi faire, mais il est trop tard, car la déréférence a déjà eu lieu.
Exemple nu pour reproduire l'erreur ci-dessus:
#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
}
Le code ci-dessus est incorrect car il essaie de déréférencer un pointeur sur un vide. Ce n'est pas permis.
Maintenant, lancez le code suivant, si vous comprenez pourquoi le code suivant est exécuté et que le code ci-dessus ne fonctionne pas, vous serez mieux équipé pour comprendre ce qui se passe sous le capot.
#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;
}
Vous avez le *
au mauvais endroit. Donc, vous essayez de déréférencer le void*
. Essayez ceci à la place:
arguments vars = *(arguments *) (args);
std::cout << "\n" << vars.a << "\t" << vars.b << "\t" << vars.c << "\n";
Alternativement, vous pouvez faire ceci: (ce qui évite également le constructeur de copie - comme mentionné dans les commentaires)
arguments *vars = (arguments *) (args);
std::cout << "\n" << vars->a << "\t" << vars->b << "\t" << vars->c << "\n";
* args signifie "l'objet (valeur) args pointe vers". Par conséquent, il ne peut pas être converti en pointeur sur objet (argument). C'est pourquoi il donne une erreur
Comme bdonlan l'a dit, le problème est de "déréférencer void*
avant de lancer".
Je pense que cet exemple aiderait:
#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;
}