【问题标题】:Generic way of returning binary data without raw pointers返回没有原始指针的二进制数据的通用方法
【发布时间】:2018-04-06 09:03:34
【问题描述】:

我有 3 个这样的类(伪代码):

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;
        };
};

structAstructB 是我无法修改(由供应商提供)的 POD C 结构,因此我无法创建父级并返回多态 unique_ptr。

我的问题是:有没有办法让 A 类和 B 类在不使用原始指针的情况下返回它们的结构数据?

【问题讨论】:

  • 您可以使用返回std::variant 的单个函数,还是需要能够动态地向系统添加更多类型?
  • 所有可能的结构在编译时都是已知的,所以我想std::variant 可以工作,我得研究一下。虽然交叉编译器 GCC 版本最多只支持 C++14,所以我可能不得不使用 boost 之类的。感谢您的建议!
  • @juanchopanza 我的另一个想法是让structA 成为私人班级成员并返回演员void * 给它。它仍然返回一个原始指针,但在这种情况下,您不必担心释放它(尽管权衡是您必须保证 A 在使用指针之前不会超出范围......)跨度>
  • variant 自 c++11 以来一直存在。祝你好运。您可能不需要这个,但您可以将输出复制到 char 向量中;在您的情况下效率较低,但更灵活。
  • @Red.Wave 你有文档的链接吗?我只能找到 C++17 文档。

标签: c++ c++11


【解决方案1】:

您可以对数据使用智能指针,即使您不将其放入多态包装器中,例如:

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);
    }
};

或者:

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;
    }
};

Live Demo

【讨论】:

  • unique_ptr&lt;void, void(*)(void*)&gt;,其开销比std::function 少。
  • @Yakk:我本来打算使用void(*)(void*),然后决定改用std::function,因为它通常更好地支持lambdas。但是,是的,void(*)(void*) 也可以使用非捕获 lambda (live demo)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 2012-08-06
相关资源
最近更新 更多