C++ 是否可以为void*创建共享\u ptr?
我有一个类,它可以包含指向某些数据和数据类型的指针。 因此,在每一时刻,我都可以使用cast来处理这些数据 以下是int和float的示例: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) {
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::coutstd::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;
};