C++。错误:void 不是指向对象的指针类型
Posted
技术标签:
【中文标题】C++。错误:void 不是指向对象的指针类型【英文标题】:C++. Error: void is not a pointer-to-object type 【发布时间】:2011-12-18 11:36:29 【问题描述】:我有一个 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
有人可以解释我做错了什么来产生这个错误吗?
【问题讨论】:
是的,有。您是否尝试过给args
提供另一种数据类型?
在这个例子中你没有任何“抽象类型”(我假设你的意思是抽象基类)。您可能指的是*(arguments *)args
,它将args
从void *
转换为arguments *
,然后 取消引用它。您当前的代码尝试取消引用 void *
(这是非法的),然后将取消引用的值转换为 arguments *
,这几乎肯定不是您想要的。
@Chris 是的,这就是我想要做的,感谢您的澄清。顺便说一句,我认为结构和类被认为是抽象类型,而例如。 int、float 是非抽象的。
另外,您的 member_func
返回 void *
但您在任何地方都没有 return
语句。另外,为什么需要使用void *
?为什么不能只使用arguments *
(或者,更好的是,只使用arguments
或const arguments&
)?
@MattMunson - 不,“抽象”是指具有纯虚拟成员函数的类(或结构)。我不知道你对 C++ 了解多少,但如果你正在学习 C++ 课程(这是我的猜测),那么你最终会达到这一点,所以暂时不用担心。
【参考方案1】:
在将 void *
转换为具体类型之前,您正在取消对它的引用。你需要反过来做:
arguments vars = *(arguments *) (args);
这个顺序很重要,因为编译器不知道如何将*
应用到args
(这是一个void *
,不能取消引用)。你的 (arguments *)
告诉它该做什么,但为时已晚,因为取消引用已经发生。
【讨论】:
但请在此处使用static_cast
-- 这样您会收到更好的错误消息...
@Billy static_cast
做什么?
@Matt: 和 C 风格的演员一样,除了更有限。 static_cast
不允许删除 const
、重新解释指针类型以及其他一些讨厌的事情。一般来说,static_cast
s 的任何东西都可以跨平台/架构工作。更多详细信息请参见 C++ 标准的第 5.2.9 节(假设为 C++03)【参考方案2】:
重现上述错误的简单例子:
#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
上面的代码是错误的,因为它试图取消引用指向 void 的指针。这是不允许的。
现在运行下面的下一个代码,如果你理解为什么下面的代码运行而上面的代码没有运行,你将更好地理解幕后发生的事情。
#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";
或者,您可以这样做:(这也避免了复制构造函数 - 如 cmets 中所述)
arguments *vars = (arguments *) (args);
std::cout << "\n" << vars->a << "\t" << vars->b << "\t" << vars->c << "\n";
【讨论】:
保留它作为指针可能更好,因为它避免了复制构造函数。但是,OP 应该使指针(arguments *
和 void *
)const
。【参考方案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】:上面的问题是你试图尊重一个在 C 或 C++ 中不允许的 void 指针。
但是,这仍然有效:
#include <iostream>
using namespace std;
int main()
int b=10;
void *a=&b;
int *ptr=(int*)a;
cout<<*ptr;;
在将 void 指针转换为 int* 指针后,我们可以尊重 int* 指针。
【讨论】:
以上是关于C++。错误:void 不是指向对象的指针类型的主要内容,如果未能解决你的问题,请参考以下文章