Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以为void*创建共享\u ptr?_C++_Shared Ptr - Fatal编程技术网

C++ 是否可以为void*创建共享\u ptr?

C++ 是否可以为void*创建共享\u ptr?,c++,shared-ptr,C++,Shared Ptr,我有一个类,它可以包含指向某些数据和数据类型的指针。 因此,在每一时刻,我都可以使用cast来处理这些数据 以下是int和float的示例: enum MyType { NO_TYPE, INT, FLO }; class MyClass { public: MyType type; void* data; MyClass(int i) : type(MyType::INT) {

我有一个类,它可以包含指向某些数据和数据类型的指针。 因此,在每一时刻,我都可以使用cast来处理这些数据

以下是int和float的示例:

enum MyType {
    NO_TYPE,
    INT,
    FLO
};

class MyClass {
public:
    MyType type;
    void* data;

    MyClass(int i)
        :
            type(MyType::INT)
    {
        data = (void*) new int(i);
    }

    MyClass(float i)
        :
            type(MyType::FLO)
    {
        std::cout << "Constructor\n";
        data = (void*) new float(i);
    }

    MyClass()
        :
            type(MyType::NO_TYPE)
    {
        std::cout << "Constructor (default)\n";
        data = nullptr;
    }

    void Copy(const MyClass &from)
    {
        this->type = from.type;
        if (this->type == MyType::INT)
            this->data = (void*) new int (*((int*)from.data));
        if (this->type == MyType::FLO)
            this->data = (void*) new float (*((float*)from.data));
    }

    MyClass(MyClass &from) {
        std::cout << "Copy constructor\n";
        Copy((const MyClass&)from);
    }

    MyClass(const MyClass &from) {
        std::cout << "Copy constructor\n";
        Copy(from);
    }

    ~MyClass() {
        std::cout << "Destructor for type "  << this->type << "\n";
        if (this->type == MyType::INT)
            delete (int*)this->data;
        if (this->type == MyType::FLO)
            delete (float*)this->data;
        this->data = nullptr;
    }
};
enum MyType{
没有(u类型),,
INT,
弗洛
};
类MyClass{
公众:
MyType类型;
作废*数据;
MyClass(int i)
:
类型(MyType::INT)
{
数据=(void*)新整数(i);
}
MyClass(浮动i)
:
类型(MyType::FLO)
{
std::cout type==MyType::INT)
此->数据=(void*)新int(*(int*)from.data));
if(this->type==MyType::FLO)
此->数据=(void*)新浮点(*(float*)from.data));
}
MyClass(MyClass和from){
std::cout数据;
此->数据=空PTR;
}
};
我想用
shared\u ptr
重写它。但是我的主要问题是
数据
无效*
。是否有一些技巧可以帮助我

更新: 编写此类的主要目的是在一个队列中存储一些不同的数据
像队列一样,有太多的未知因素无法单方面回答这个问题

  • 如果在编译之前知道类型,则可以将该类转换为模板
  • 如果需要类型安全,可以使用类型安全联合-
    std::variant
  • 您可以创建一个factory或visitor类,为每个存储分配和分离类
  • 如果您需要将数据存储在单片阵列中,例如与一些外部非C++API(例如OpenGL)一起使用,则必须切换到
    unsigned char*
是否有一些技巧可以帮助我

你当然可以做到。下面是您的类的更新版本和一些测试代码

#include <iostream>
#include <memory>

enum MyType {
   NO_TYPE,
   INT,
   FLO
};

class MyClass {
   public:
      MyType type;
      std::shared_ptr<void> data;

      static void int_deleter(int* ptr)
      {
         std::cout << "Deleting an int*\n";
         delete ptr; 
      }

      static void float_deleter(float* ptr)
      {
         std::cout << "Deleting a float*\n";
         delete ptr;
      }

      MyClass(int i) : type(MyType::INT), data(new int(i), int_deleter)
      {
         std::cout << "Constructor with int\n";
      }

      MyClass(float i) : type(MyType::FLO), data(new float(i), float_deleter)
      {
         std::cout << "Constructor with float\n";
      }

      MyClass() : type(MyType::NO_TYPE)
      {
         std::cout << "Constructor (default)\n";
      }

      // Can be a private member function.
      static std::shared_ptr<void> make_data(const MyClass &from)
      {
         switch ( from.type )
         {
            case MyType::INT:
               return std::shared_ptr<void>(new int (*((int*)from.data.get())), int_deleter);

            case MyType::FLO:
               return std::shared_ptr<void>(new float (*((float*)from.data.get())), float_deleter);

            default:
               return {};
         }

         return {};
      }

      MyClass(MyClass &from) : type(from.type), data(make_data(from))
      {
         std::cout << "Copy constructor\n";
      }

      MyClass(const MyClass &from) : type(from.type), data(make_data(from))
      {
         std::cout << "Copy constructor\n";
      }

      ~MyClass()
      {
         std::cout << "Destructor for type "  << this->type << "\n";
      }
};

void test_int()
{
   MyClass c1(10);
   MyClass c2(c1);
}

void test_float()
{
   MyClass c1(10.2f);
   MyClass c2(c1);
}

int main()
{
   test_int();
   test_float();
}

我不能谈论使用
共享\u ptr
的价值,但它可以作为指针的通用容器

这些是有效的:

int i = 42;
std::shared_ptr<void> spVoid = std::make_shared<int>(i);

float f = 3.14f;
std::shared_ptr<void> spVoid = std::make_shared<float>(f);
inti=42;
std::shared_ptr spVoid=std::make_shared(i);
浮球f=3.14f;
std::shared_ptr spVoid=std::make_shared(f);
当最后一个引用消失时,将调用原始实例化项的正确析构函数。通过一个类实例亲自查看

struct Foo
{
    Foo()
    {
        std::cout << "Foo constructor" << std::endl;
    }

    ~Foo()
    {
        std::cout << "Foo destructor" << std::endl;
    }
};

int main()
{
    std::shared_ptr<void> spVoid = std::make_shared<Foo>();
    return 0;
}
structfoo
{
Foo()
{

std::cout您可以提供deleter:(默认值是正确的,因此可以使用
std::make_shared

class-MyClass{
公众:
MyType type=MyType::无类型;
std::共享的ptr数据;
MyClass()=默认值;
MyClass(inti){set(i);}
MyClass(float f){set(f);}
无效副本(const MyClass和from)
{
开关(来自.type){
case MyType::INT:set(*(INT*)from.data.get());
case MyType::FLO:set(*(float*)from.data.get());
case MyType::NO_TYPE:set();
}
}
MyClass(常量MyClass和from){

std::cout
std::variant
似乎更合适。@AlexF似乎不是这样。如果类型是在运行时确定的来回答您的问题,您可以传递自定义删除程序。我会更新问题以显示我为什么不能使用模板。您为什么不使用
std::any
std::variant
class MyClass {
public:
    MyType type = MyType::NO_TYPE;
    std::shared_ptr<void> data;

    MyClass() = default;

    MyClass(int i) { set(i); }
    MyClass(float f) { set(f); }

    void Copy(const MyClass &from)
    {
        switch (from.type) {
            case MyType::INT: set(*((int*)from.data.get());
            case MyType::FLO: set(*((float*)from.data.get());
            case MyType::NO_TYPE: set();
        }
    }

    MyClass(const MyClass &from) {
        std::cout << "Copy constructor\n";
        Copy(from);
    }

    void set()
    {
        type = MyType::NO_TYPE;
        data = nullptr;
    }

    void set(int i)
    {
        type = MyType::INT;
        data = std::make_shared<int>(i);
    }

    void set(float f)
    {
        type = MyType::FLO;
        data = std::make_shared<float>(f);
    }

    ~MyClass() = default;
};