代码之家  ›  专栏  ›  技术社区  ›  Makogan

是否可以将已初始化的变量转换为void*?

  •  0
  • Makogan  · 技术社区  · 4 年前

    这是一个关于语言限制的问题,请不要回答“你不应该这样做”,这与你是否 应该 不管有没有,重要的是你是否 可以 .

    假设我们想要编写一个获得任何对象所有权的子例程,我们可以这样写,例如:

    void function(void* object)
    {
       // store the pointer somewhere
    }
    
    auto ptr = new MyObject(params);
    function(ptr);
    

    上述方法可以工作,但会强制用户初始化他希望与 new 操作人员我想知道你是否可以“窃取”对象的内容,即使它是正常初始化的。

    我想知道你是否可以这样做:

    template <typename T>
    void function(T& object)
    {
       void* ptr = malloc(sizeof(T));
       *ptr = std::move(object); // Or somehting like this
       // store ptr somewhere
    }
    
    MyObject object(params);
    function(object);
    // object variable is now invalid
    
    2 回复  |  直到 4 年前
        1
  •  1
  •   Asteroids With Wings    4 年前

    你当然可以从一个没有动态分配的东西转移到一个 动态分配。

    不过,这只有在“移动”对你的类型有意义和价值的情况下才有用。否则,您将无法复制数据。

    记得: std::move 实际上,移动物体并不是为了转移或改变它们的寿命;它只允许编译器选择构造函数和赋值运算符重载 也许 执行一些间接状态的廉价传输,以避免深度复制的成本。

        2
  •  1
  •   eerorika    4 年前

    假设我们想要编写一个获得任何对象所有权的子例程。

    单独使用指向void的指针当然不可能做到这一点,因为所有权意味着要负责删除动态对象,并且不可能通过void指针删除对象。

    它可以通过使用deleter函数对象来实现。没有必要为此编写包装器类,因为您已经介绍了标准库 1. .

    我想知道你是否可以这样做:

    void* ptr = malloc(sizeof(T));
    *ptr = std::move(object);
    

    不完全是这样,因为你不能通过指向void的指针来间接,而且,你还没有在那里创建一个对象,所以没有什么可分配的。

    离开左值引用参数也是个坏主意。

    您似乎试图创建一个动态对象,它是参数对象的副本(通过移动)。下面是一个如何做到这一点的示例:

    template <typename T>
    void function(T&& object)
    {
        auto ptr = std::make_unique<T>(std::move(object));
    

    你可以得到一个指向void的指针,如下所示:

    void* void_ptr = ptr.get();
    

    1. 要删除任何类型的对象(可以通过指向void的指针来实现),但也可以拥有该对象(与指向void的指针不同),标准库中有一种类型: std::any .