如何将void *用作单个变量持有人?(例如void * raw = SomeClass()) [英] How to use void* as a single variable holder? (Ex. void* raw=SomeClass() )

查看:49
本文介绍了如何将void *用作单个变量持有人?(例如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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆