How to use void* as a single variable holder? (Ex. void* raw=SomeClass() )

北城以北 提交于 2019-12-20 06:38:54

问题


I am trying to make void* to hold a value (to avoid default constructor calling).

I want to:-

  • copy K to void* e.g. K k1; --> void* raw=k1;
  • copy void* to K e.g. void* raw; --> K k2=raw;
  • try not to break destructor and causes memory leak
  • don't use any dynamic allocation (heap, performance reason)

Here is what I tried:-

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;
}

Question: Please provide a valid code that demonstrate a correct way to do this.

I found how to use placement new (https://stackoverflow.com/a/4756306/3577745 ), but not found how to use void* for a variable that is not an array.

C++ is new for me.

Edit :
I am writing a very custom collection (array).
Each element is encapsulated in a custom structure KCap kcap(with hold only 1 element, i.e. K).
Thus, I have to declare K k as a field of the encapsulator KCap.
However, I want to avoid default constructor of K, so I think void* can solve my issue.


回答1:


What you are trying to do doesn't make sense. A void * is used to hold an arbitrary type of pointer, not an arbitrary type of other object. If you want to use storage for an arbitrary object type, use a char[].

Other problems with your code include that you need to ensure correct alignment of the raw storage, use reinterpret_cast to a reference rather than static_cast to a non-reference, your in-place destructor call syntax is wrong, and that you don't construct the K object in the "raw" storage. Here's a corrected version:

#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;
}


来源:https://stackoverflow.com/questions/40605120/how-to-use-void-as-a-single-variable-holder-ex-void-raw-someclass

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