具有POD结构和继承的智能指针

时间:2016-06-11 20:12:42

标签: c++11 inheritance struct smart-pointers

我正在开发一个使用POD C ++结构的应用程序。这工作正常,直到我需要有一个我的POD结构的两个变种。引入虚拟继承(由于基类中存在虚拟析构函数)以便以多态方式管理这些类似的POD结构(因为它们共享公共基本字段)会改变派生数据结构的总体大小 - 因为它需要容纳vtable。另一方面,没有虚拟基类会在智能指针析构函数中引入数据切片。

有没有办法解决这个问题,这样我就可以通过基类保持管理这些PODS的便利性,同时在调用std :: unique_ptr的析构函数时不会引入数据切片/内存泄漏。

我整理了一个简单的live coliru演示,展示了我遇到的POD结构的各个方面,遗憾的是我不知道如何在虚拟基本唯一指针的向量中包含这些。任何帮助/设计指针将不胜感激。

struct VBase {
    uint32_t mBaseInt;

    // allow default construction using placement operator
    VBase() = default;

    // copy constructor
    VBase(const VBase&) = default;

    // move constructor
    VBase(VBase&&) = default;

    // explicit constructor
    explicit VBase(const uint32_t val) 
        : mBaseInt(val)
    {
        std::cout << "VBase(val)" << std::endl;
    }
    virtual ~VBase() = default;
} __attribute__((packed));

struct Derived1 : VBase {
    uint32_t mDerivedInt;

    // allow default construction using placement operator
    Derived1() = default;

    // copy constructor
    Derived1(const Derived1&) = default;

    // move constructor
    Derived1(Derived1&&) = default;

    // explicit constructor
    explicit Derived1(const uint32_t val, const uint32_t val1) 
        : VBase(val)
        , mDerivedInt(val1)
    {
        std::cout << "Derived1(val, val1)" << std::endl;
    }
    ~Derived1() {
        std::cout << "~Derived1()" << std::endl;
    };
} __attribute__((packed));

struct Derived2 : VBase {
    uint32_t mDerivedInt1;
    uint32_t mDerivedInt2;

    // allow default construction using placement operator
    Derived2() = default;

    // copy constructor
    Derived2(const Derived2&) = default;

    // move constructor
    Derived2(Derived2&&) = default;

    // explicit constructor
    explicit Derived2(
        const uint32_t val, 
        const uint32_t val1, 
        const uint32_t val2) 
        : VBase(val)
        , mDerivedInt1(val1)
        , mDerivedInt2(val2)
    {
        std::cout << "Derived2(val, val1, val2)" << std::endl;
    }
    virtual ~Derived2() {
        std::cout << "~Derived2()" << std::endl;
    };
} __attribute__((packed));

struct NVBase {
    explicit NVBase() {
        std::cout << " NVBase()" << std::endl;
    }
    ~NVBase() {
        std::cout << "~NVBase()" << std::endl;
    };
} __attribute__((packed));

struct D : NVBase {
    uint16_t f;
    explicit D() 
        : NVBase()
    {}

    ~D() {
        std::cout << "~D()" << std::endl;
    };
} __attribute__((packed));

int main()
{
    std::vector<std::string> words = {
        "Hello", "from", "GCC", __VERSION__, "!"
    };
    std::cout << words << std::endl;
    std::cout << "sizeof(VBase)=" << sizeof(VBase) << std::endl;
    std::cout << "sizeof(Derived1)=" << sizeof(Derived1) <<std::endl;
    std::cout << "sizeof(Derived2)=" << sizeof(Derived2)<< std::endl;
    std::cout << "sizeof(NVBase)=" << sizeof(NVBase) << std::endl;
    std::cout << "sizeof(D)=" << sizeof(D) << std::endl;
    std::unique_ptr<VBase> pVBase = std::make_unique<Derived1>(1,2);
    std::unique_ptr<NVBase> pNVDerived = std::make_unique<D>();
    std::cout << sizeof(*pVBase) << std::endl;
    std::cout << sizeof(*pNVDerived) << std::endl;
    std::vector<std::unique_ptr<VBase>> vec = {
        //std::make_unique<Derived1>(1,2)
    };
   // vec.emplace_back(std::move(*pVBase));
}

0 个答案:

没有答案