将多继承对象转换为void*或从void*转换为多继承对象
Casting multiple-inherited object to and from void*
我知道,类似的问题已经有了答案,但我仍然有一些困惑。这里的示例自然地简化了,并从真实的代码库中剥离了不相关的内容。
class X {...};
class Y {...};
class Z : public X, public Y {...}
现在我创建Z对象,并把它通过C接口(作为void*
)
Z* z = new Z();
doSomeWeirdStuff(z);
在一些回调,我得到我的对象回来(仍然作为void*
)。
void callback(void* data)
{
Z* z1 = static_cast<Z*>(data);
Z* z2 = dynamic_cast<Z*>(static_cast<Y*>(data));
}
z1
是垃圾。由于X
和Y
具有相同的布局,当我调试时,我看到z1
在对象的X部分具有Y的值。我期望,因为我创建的对象是Z,这应该是正确的。而z2
似乎是正确的。
顺便说一下,类没有共同的祖先,这不是虚拟继承。
为什么?我遗漏了什么?
编辑:我错过的东西很简单,我应该为此而自食其果。长话短说:X
和Y
使用this
在它们的构造函数中初始化用户数据,所以当我认为它是Z
时,我真的传递了一个指向Y
的指针…
我要接受@user2079303的答案,因为它让我再检查三次代码来发现这个
既然你在谈论"C接口",你是在分别编译库和接口吗?如果是这样,请确保两者使用相同的编译器设置,即调试/发布模式,安全迭代器开/关等。
z1
的转换是正确的,并保证按标准工作。以下是cppreference对static_cast
的引用。
指向void(可能是cv限定的)类型指针的右值可以转换为指向任何类型的指针。将任何指针转换为void指针,再转换回指向原始(或更符合cv的)类型的指针,将保留其原始值。
这个例子运行正常。
#include <cassert>
struct X {
int a;
};
struct Y {
int b;
};
struct Z : public X, public Y {
int c;
};
void callback(void* data) {
Z* z1 = static_cast<Z*>(data);
assert(z1->a == 1);
assert(z1->b == 2);
assert(z1->c == 3);
}
int main() {
Z z;
z.a = 1;
z.b = 2;
z.c = 3;
callback((void*) &z);
}
为什么?我遗漏了什么?
可能未定义的行为已经覆盖了您的内存。
相关文章:
- Boost buffer_cast 无法从 void* 转换为 PointerToPodType
- 将void*转换为某种类型的shared_ptr
- 如何将 void* 转换为函数指针?
- 对 C++ 中的特定标头使用 extern C 关键字是否允许从 void* 转换为 char*?
- 如何将 void 转换为 typedef void(..)(浮动)
- 无法将参数 1 从"int (__thiscall A::* *)(void)"转换为"int (__cdecl *)(void)"
- 从 'void *' 转换为 'const std::string *&' 必须具有所有中间指针 const 合格
- x = malloc(n * sizeof (int));无法将 void 转换为 int
- 错误:请求从“ void”转换为“ QString”的非量表类型
- 使用 LLVM 从 const void * 转换为模板类型时出现问题
- 如何修复错误:请求从"void"转换为非标量类型"std::vector<int>"
- void* 转换为基类并调用虚函数
- 将 void* 转换为 std::function<void()>
- 无法将参数 4 从 'void' 转换为'const char *'
- C++11 无法将 std::condition_variable::wait 从 'void' 转换为 'bool'
- 如何在 C++11 中将"const void*"转换为函数指针?
- 似乎无法在 c++ 中将 void* 转换为结构
- 将 void 转换为字节
- void * 转换为 int 语法的问题
- C++从类型“void*”转换为类型“double”无效