C++ 无原始指针返回二进制数据的通用方法
我有3个类似于此psuedocode的类:C++ 无原始指针返回二进制数据的通用方法,c++,c++11,C++,C++11,我有3个类似于此psuedocode的类: class Parent { public: virtual void * getData(size_t & size) = 0; }; class A : public Parent { public: void * getData(size_t & size) { size = sizeof(structA); structA * a
class Parent {
public:
virtual void * getData(size_t & size) = 0;
};
class A : public Parent {
public:
void * getData(size_t & size) {
size = sizeof(structA);
structA * a = new structA();
//fill er up
return (void *) a;
};
};
class B : public Parent {
public:
void * getData(size_t & size) {
size = sizeof(structB);
structB * b = new structB();
//fill er up
return (void *) b;
};
};
structA和structB是POD C结构,我无法修改供应商提供的结构,因此我无法创建父级并返回多态唯一的\u ptr(例如)
我的问题是:有没有一种方法可以让类a和B在给定约束的情况下不使用原始指针而通用地返回其结构数据?您可以使用智能指针来返回数据,即使您没有将其放入多态包装器中,例如:
class Parent
{
public:
using dataPtr = std::unique_ptr<void, void(*)(void*)>;
virtual dataPtr getData(size_t & size) = 0;
};
class A : public Parent
{
public:
dataPtr getData(size_t & size) override
{
size = sizeof(structA);
dataPtr a(new structA, [](void *data){ delete static_cast<structA*>(data); });
//fill er up
return std::move(a);
}
};
class B : public Parent
{
public:
dataPtr getData(size_t & size) override
{
size = sizeof(structB);
dataPtr b(new structB, [](void *data){ delete static_cast<structB*>(data); });
//fill er up
return std::move(b);
}
};
或:
您是否可以使用一个返回std::variant的函数,或者您是否需要能够向系统动态添加更多类型?所有可能的结构在编译时都是已知的,因此我认为std::variant可以工作,我必须研究它。尽管跨编译器GCC版本最多只支持C++14,所以我可能不得不使用boost之类的工具。谢谢你的建议@juanchopanza我的另一个想法是让structA成为私有类成员并返回一个cast void*。它仍然返回一个原始指针,但在这种情况下,您不必担心释放它,尽管折衷是,您必须确保在使用指针之前,a不会超出范围……从c++11开始,变量就存在了。祝你好运。您可能不需要这个,但是您可以复制char向量中的输出;您的工作效率较低,但更灵活。@Red.Wave您是否有文档链接?我只能找到C++17 docs.Or unique_ptr,它的开销比std::function one少。@Yakk:我本来打算使用void*void*,但后来决定使用std::function,因为它通常更好地支持lambda。但是,是的,非捕获lambda也可以与void*void*一起使用
class Parent
{
public:
using dataPtr = std::shared_ptr<void>;
virtual dataPtr getData(size_t & size) = 0;
};
class A : public Parent
{
public:
dataPtr getData(size_t & size) override
{
size = sizeof(structA);
dataPtr a(new structA, [](void *data){ delete static_cast<structA*>(data); });
//fill er up
return a;
}
};
class B : public Parent
{
public:
dataPtr getData(size_t & size) override
{
size = sizeof(structB);
dataPtr b(new structB, [](void *data){ delete static_cast<structB*>(data); });
//fill er up
return b;
}
};