С++. Ошибка: void не является типом указателя на объект
У меня есть программа на С++:
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
Может кто-нибудь объяснить, что я делаю неправильно, чтобы произвести эту ошибку?
Ответы
Ответ 1
Вы разыгрываете void *
перед тем, как придать его конкретному типу. Вам нужно сделать это наоборот:
arguments vars = *(arguments *) (args);
Этот порядок важен, поскольку компилятор не знает, как применить *
к args
(который является void *
и не может быть разыменован). Ваш (arguments *)
сообщает, что делать, но это слишком поздно, потому что разыменование уже произошло.
Ответ 2
Пример Bare bones для воспроизведения описанной выше ошибки:
#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
У вас есть *
в неправильном месте. Поэтому вы пытаетесь разыменовать 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";
Ответ 4
Проблема, как сказал 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;
}
Ответ 5
* args означает, что объект (значение) args указывает на ". Поэтому он не может быть введен как указатель на объект (аргумент). Вот почему он дает ошибку
Ответ 6
Проблема, описанная выше, заключается в том, что вы пытаетесь задержать указатель void, который не разрешен в C или C++.
Тем не менее, это все еще работает:
#include <iostream>
using namespace std;
int main()
{
int b=10;
void *a=&b;
int *ptr=(int*)a;
cout<<*ptr;;
}
Мы можем ссылаться на указатели int * после приведения пустых указателей к указателям int *.