问题
I have the following code (live on Coliru):
// untouchable extern library .hpp file
typedef union ExternLibraryUnion
{
int a;
float b;
}ExternLibraryUnion;
// my code
#include <iostream>
class Container{
public:
Container() : m_union(NULL) {};
~Container(){
if(m_union){
delete m_union;
}
}
void init(){
m_union = new ExternLibraryUnion();
}
ExternLibraryUnion* get_union(){
return m_union;
}
private:
ExternLibraryUnion* m_union;
};
class Master{
public:
Master() : m_union(NULL) {
m_container.init();
};
~Master(){
if(m_union){
delete static_cast<ExternLibraryUnion*>(m_union);
}
}
void load(){
}
void set(int i){
m_union = m_container.get_union();
m_union->a = i;
}
void* get_union(){
return m_union;
}
private:
void* m_union;
Container m_container;
};
class Worker{
public:
Worker() : m_extern_library_union(NULL) {};
~Worker(){
if (m_extern_library_union){
delete m_extern_library_union;
}
}
void load(Master& master){
m_extern_library_union = reinterpret_cast<ExternLibraryUnion*>(master.get_union());
}
int get_int(){
return m_extern_library_union->a;
}
private:
ExternLibraryUnion* m_extern_library_union;
};
int main()
{
Master master;
master.set(3);
Worker worker;
worker.load(master);
std::cout << worker.get_int() << std::endl;
}
The code produces:
main.cpp: In member function 'void Master::set(int)':
main.cpp:55:16: error: 'void*' is not a pointer-to-object type
m_union->a = i;
^~
In an extern library, a union ExternLibraryUnion
is defined which I'm using inside my own code. My problem, which I can't get my head around, is in the set
method of class Master
. The Master
member void* m_union
should point to the union stored inside the member Container m_container
. As I'm setting the m_union = m_container.get_union()
the compiler should be able to know that I'm getting a ExternLibraryUnion*
back from the get_union()
method call. So I don't quite the error arising from the assignment m_union->a = i
. Sure, a void*
has no type, but I assigned it a pointer of the precise type ExternLibraryUnion
.
Let's also say I can not touch the Container m_container
object directly. I need to make the assigned through the void* m_union
pointer.
Any help is highly appreciated!
回答1:
The compiler has no clue what m_union
might actually be pointing at. You declared it as a void *
so the compiler believes you, it has no choice. And that's all it knows, so m_union->a
has to be flagged as an error, because ->a
has no meaning to the compiler here.
To put it another way, RTTI aside, pointers don't 'know' what they're pointing at. The compiler only knows how the pointer was declared.
I don't know what else to say, it's really that simple. I don't like having to say this, but looking at the code as a whole, it looks like a complete mess. Who wrote it?
[Edit] And what Jeffrey said will indeed fix it, but that's not what you asked.
回答2:
You need to change
private:
void* m_union;
to
private:
ExternLibraryUnion* m_union;
at line 63. As your code stand, you upcast the pointer to void*, and then, at the next line the compiler can't know the pointed type.
If you can't change the type, you can static_cast the void pointer to an ExternLibraryUnion*. Then use that to access. Since you know the type, the static_cast could be "acceptable". But not the nicest design by any measure.
来源:https://stackoverflow.com/questions/50864862/error-why-void-is-not-a-pointer-to-object-type-even-though-the-pointer-is-se