错误:为什么'void *'不是指针对象类型,即使指针设置为对象?

时间:2018-06-14 19:48:04

标签: c++ unions void-pointers

我有以下代码(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;
}

代码产生:

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;
                ^~

在extern库中,定义了union ExternLibraryUnion,我在自己的代码中使用了它。我的问题,我无法理解,是setMaster方法。 Master成员void* m_union应指向存储在成员Container m_container中的联合。当我设置m_union = m_container.get_union()时,编译器应该能够知道我从ExternLibraryUnion*方法调用返回get_union()。所以我并没有因为作业m_union->a = i而产生的错误。当然,void*没有类型,但我为其指定了精确类型ExternLibraryUnion的指针。

我们也说我无法直接触摸Container m_container对象。我需要通过void* m_union指针进行分配。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:5)

编译器无线索 m_union可能实际指向的内容。您将其声明为void *,因此编译器相信您,它别无选择。而且它知道所有,所以m_union->a必须被标记为错误,因为->a对编译器没有任何意义。

换句话说,抛开RTTI,指针不知道他们指的是什么。编译器只知道指针如何声明

我不知道还有什么可说的,这真的很简单。我不喜欢这样说,但从整体上看代码,它看起来像一个完整的混乱。是谁写的?

[编辑]杰弗里说的确实会解决它,但那并不是你问的。

答案 1 :(得分:0)

您需要更改

private:
void* m_union;

private:
ExternLibraryUnion* m_union;

在第63行。当您的代码成立时,您将指针向上转换为void *,然后,在下一行,编译器无法知道指向的类型。

如果无法更改类型,可以将void指针static_cast一个 ExternLibraryUnion *。然后用它来访问。由于您知道类型,static_cast可能是“可接受的”。但不是最好的设计。