我不知道如何正确地具有派生类的向量而不会发生内存泄漏。我尝试了以下操作,但是有问题:
#include <iostream>
#include <vector>
using namespace std;
struct base {};
struct derived : public base
{
derived() {}
};
struct Layer
{
vector<base*> effects;
Layer() {}
~Layer()
{
for(int ii = 0; ii < effects.size(); ii++)
{
cout << "called effect deleter" << endl;
delete effects[ii];
}
}
};
int main()
{
vector<Layer> layers;
for(int i = 0; i < 10; i++)
{
layers.push_back(Layer());
layers[i].effects.push_back(new derived());
cout << i << endl;
}
}
编译并运行此代码时,得到以下输出:
0
called effect deleter
1
called effect deleter
called effect deleter
我很困惑。为什么只打印0和1而不是0到9?如果删除Layer析构函数,会不会发生内存泄漏?处理这种情况的正确方法是什么?
如果是base *b
,但是*b
实际上是derived
,则delete b;
是即时UB,因为base::~base()
不是virtual
。本质上,您尝试删除base
的*b
部分(由*b
的类型,即base
指示),但是由于析构函数不是虚拟的,因此您忘记了销毁derived
首先。这导致发生可怕的事情(可能是某种堆栈损坏?)。修复它:
[您不能在c ++中将其作为直接向量-不同的派生类具有不同的大小,因此,当复制构造函数将元素放置在数组中时,您将得到切片(经典对象切片)。