问题
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