web-dev-qa-db-fra.com

C++. Erreur: void n'est pas un type pointeur sur objet

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?

15
Matt Munson

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.

21
bdonlan

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;
}
5
Eric Leschinski

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";
3
Mysticial

* 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

0
user966379

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;
}
0
gandalf