如何使用void *作为单个变量持有者? (例如,void * raw = SomeClass())

时间:2016-11-15 08:27:07

标签: c++ void-pointers

我试图让Thread.Sleep(n)保持一个值(以避免默认的构造函数调用)。

我想: -

  • 将K复制为无效* void*
  • 将void *复制到K,例如K k1; --> void* raw=k1;
  • 尽量不破坏析构函数并导致内存泄漏
  • 不使用任何动态分配(堆,性能原因)

这是我尝试过的: -

void* raw; --> K k2=raw;

问题:请提供有效的代码,说明正确的方法。

我找到了如何使用展示位置新(https://stackoverflow.com/a/4756306/3577745),但未找到如何将class K{ public: std::string yes="yes" ; }; int main() { //objective: k1->raw->k2 , then delete "raw" void* raw[sizeof(K)]; //<--- try to avoid heap allocation K k1; static_cast<K>( raw)=k1; //<--- compile fail K k2= static_cast<K>( raw); std::cout<<k2.yes; //test static_cast<K&>(raw)::~K(); //mimic destructor return 0; } 用于非数组的变量。

C ++对我来说是新的。

修改
我正在写一个非常自定义的集合(数组) 每个元素都封装在一个自定义结构void*中(仅保留1个元素,即KCap kcap)。
因此,我必须将K声明为封装器K k的字段 但是,我想避免KCap的默认构造函数,所以我认为K可以解决我的问题。

1 个答案:

答案 0 :(得分:3)

你要做的事情没有意义。 void *用于保存任意类型的指针,而不是任意类型的其他对象。如果要将存储用于任意对象类型,请使用char[]

您的代码的其他问题包括您需要确保原始存储的正确对齐,使用reinterpret_cast到引用而不是static_cast到非引用,您的就地析构函数调用语法是错误的,并且您没有在“原始”存储中构造K对象。这是一个更正版本:

#include <string>
#include <iostream>

class K{
    public: std::string yes="yes"   ;
};

int main() {
    //objective:  k1->raw->k2  , then delete "raw"
    alignas(alignof(K)) char raw[sizeof(K)];        //<--- try to avoid heap allocation
    K k1;
    new (reinterpret_cast<K *>(&raw)) K(k1);     //<--- compile now succeeds :)
    K k2= reinterpret_cast<K &>(raw);
    std::cout << k2.yes << std::endl;           //test
    reinterpret_cast<K&>(raw).K::~K();  // call destructor
    return 0;
}