【问题标题】:Error: Why 'void*' is not a pointer-to-object type even though the pointer is set to an object?错误:为什么“void*”不是指向对象的指针类型,即使指针设置为对象?
【发布时间】:2018-06-14 19:48:04
【问题描述】:

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

在一个外部库中,定义了一个union ExternLibraryUnion,我在自己的代码中使用它。我无法理解的问题在于Master 类的set 方法。 Master 成员 void* m_union 应该指向存储在成员 Container m_container 中的联合。当我设置m_union = m_container.get_union() 时,编译器应该能够知道我从get_union() 方法调用中得到了ExternLibraryUnion*。所以我不太会因为分配m_union-&gt;a = i 而出现错误。当然,void* 没有类型,但我为它分配了一个精确类型为 ExternLibraryUnion 的指针。

假设我不能直接触摸Container m_container 对象。我需要通过void* m_union指针进行分配。

非常感谢任何帮助!

【问题讨论】:

  • 该语言如何知道您将其设置为什么? void* 是`void*。
  • void* 在您不知道自己指向什么时使用。如果你不知道你指向什么,你怎么能分配给它的一个成员?
  • 专业提示:如果您将void* 用于与强制您使用void * 的遗留或C 风格API 接口之外的任何其他用途,那么您几乎肯定会走上一条错误的道路。
  • void* 适用于您知道它指向什么但不希望代码或编译器知道的情况。
  • 您为什么不在Master 中使用ExternLibraryUnion*

标签: c++ unions void-pointers


【解决方案1】:

编译器不知道m_union 可能实际上指向什么。您将其声明为void *,因此编译器相信您,它别无选择。这就是它所知道的全部,所以必须将m_union-&gt;a 标记为错误,因为-&gt;a 对这里的编译器没有任何意义。

换句话说,除了 RTTI,指针并不“知道”它们所指向的内容。编译器只知道指针是如何声明的

我不知道还能说什么,真的就是这么简单。我不喜欢这样说,但是从整体上看代码,它看起来像是一团糟。谁写的?

[编辑] Jeffrey 所说的确实会解决它,但这不是你问的。

【讨论】:

  • 感谢您为我解决问题!现在我实际上了解了错误的原因。这段代码是由几个学生编写的,我基本上把代码删掉了,以便能够在这里发布。有人告诉我能够完成设置 void 指针的“任务”。
  • 以下注意事项:RTTI:RunTime Type Information
  • @DummySenior 太好了,这就是我想要的。
【解决方案2】:

你需要改变

private:
void* m_union;

private:
ExternLibraryUnion* m_union;

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

如果你不能改变类型,你可以将 void 指针静态转换为 外部图书馆联盟*。然后用它来访问。由于您知道类型,因此 static_cast 可能是“可接受的”。但无论如何都不是最好的设计。

【讨论】:

  • “dynamic_cast 会起作用”:我相信不是来自void *。你必须使用static_cast
  • 哈哈。对。从来不知道。我想我没有使用足够的 void* 指针。会修复的。
  • @Jeffrey -- 不,您可能使用了太多次void* 不了解它的局限性并不是一件坏事:不要使用它。
猜你喜欢
  • 2020-08-30
  • 2012-11-24
  • 2019-05-04
  • 2011-12-18
  • 2013-10-24
  • 2011-12-18
  • 2021-07-22
  • 2017-04-22
  • 2023-02-09
相关资源
最近更新 更多