Error: Why 'void*' is not a pointer-to-object type even though the pointer is set to an object?

拈花ヽ惹草 提交于 2020-05-16 04:10:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!