С.++ Ошибка: void не является типом указателя на объект

у меня есть программа на 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";
    }
};

при компиляции он выдает ошибку:

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

может кто-то объяснит, что я делаю неправильно, чтобы произвести эту ошибку?

5 ответов


вы разыменования void * до приведения его к конкретному типу. Вам нужно сделать это наоборот:

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

этот порядок важен, потому что компилятор не знает, как применить * to args (это void * и не может быть разыменован). Ваш (arguments *) говорит ему, что делать, но это слишком поздно, потому что разыменование уже произошло.


пример голых костей для воспроизведения вышеуказанной ошибки:

#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
}

приведенный выше код неверен, потому что он пытается разыменовать указатель на пустоту. Это запрещено.

теперь запустите следующий код ниже, Если вы понимаете, почему следующий код работает и приведенный выше код не, вы будете лучше подготовлены, чтобы понять, что происходит под капотом.

#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;
}

у вас * в неположенном месте. Таким образом, вы пытаетесь разыменовать void*. Попробуйте вместо этого:

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

кроме того, вы можете сделать это: (что также позволяет избежать копирования-конструктора - как указано в комментариях)

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

* args означает "объект (значение) args указывает на". Поэтому он не может быть преобразован в указатель на объект(аргумент). Вот почему он дает ошибку


проблема, как сказал bdonlan, " разыменование void* перед литьем".

Я думаю, что этот пример поможет:

#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;
}