如何将void *用作单个变量持有人?(例如void * raw = SomeClass()) [英] How to use void* as a single variable holder? (Ex. void* raw=SomeClass() )
问题描述
我正在尝试使 void *
保持一个值(以避免默认的构造函数调用).
I am trying to make void*
to hold a value (to avoid default constructor calling).
我要:-
- 将K复制到空白*,例如
K k1;->void * raw = k1;
- 将void *复制到K,例如
void * raw;->K k2 = raw;
- 尽量不要破坏析构函数并导致内存泄漏
- 请勿使用任何动态分配(堆,性能原因)
这是我尝试过的:-
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.
我找到了如何使用新的展示位置( https://stackoverflow.com/a/4756306/3577745 ),但找不到如何将 void *
用于不是数组的变量.
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 ++对我来说是新的.
C++ is new for me.
修改:
我正在编写一个非常自定义的集合(数组).
每个元素都封装在自定义结构 KCap kcap
(仅包含1个元素,即 K
)中.
因此,我必须将 K k
声明为封装器 KCap
的字段.
但是,我想避免使用 K
的默认构造函数,所以我认为 void *
可以解决我的问题.
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.
推荐答案
您尝试执行的操作没有任何意义.void *用于保存任意类型的指针,而不是其他对象的任意类型.如果要将存储用于任意对象类型,请使用 char []
.
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[]
.
您的代码的其他问题包括您需要确保原始存储的正确对齐,对您的引用使用 reinterpret_cast
而不对非引用使用 static_cast
就地析构函数调用语法是错误的,并且您不在原始"存储中构造K对象.这是一个更正的版本:
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;
}
这篇关于如何将void *用作单个变量持有人?(例如void * raw = SomeClass())的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!