C ++.Ошибка: void не является указателем на тип объекта - PullRequest
18 голосов
/ 31 октября 2011

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

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

Ответы [ 6 ]

25 голосов
/ 31 октября 2011

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

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

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

6 голосов
/ 27 мая 2014

Пример «Голые кости» для воспроизведения вышеуказанной ошибки:

#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;
}
3 голосов
/ 31 октября 2011

У вас есть * в неправильном месте. Итак, вы пытаетесь разыменовать 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";
1 голос
/ 09 июня 2015

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

Думаю, этот пример поможет:

0 голосов
/ 21 июня 2019

Проблема, описанная выше, заключается в том, что вы пытаетесь задержать указатель void, который не разрешен в C или C ++.

Однако, это все еще работает:

#include <iostream>
using namespace std;
int main()
{
    int b=10;
    void *a=&b;
    int *ptr=(int*)a;
    cout<<*ptr;;
} 

Мы можем ссылаться на указатели int * после приведения пустых указателей к указателям int *.

0 голосов
/ 31 октября 2011

* args означает «объект (значение), на который указывает args». Поэтому его нельзя привести как указатель на объект (аргумент). Вот почему он дает ошибку

...