我正在开发一个使用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));
}