处理指向派生类的指针的向量的正确方法?

问题描述 投票:1回答:2

我不知道如何正确地具有派生类的向量而不会发生内存泄漏。我尝试了以下操作,但是有问题:

#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析构函数,会不会发生内存泄漏?处理这种情况的正确方法是什么?

c++ c++11 vector memory-management c++-standard-library
2个回答
1
投票

如果是base *b,但是*b实际上是derived,则delete b;是即时UB,因为base::~base()不是virtual。本质上,您尝试删除base*b部分(由*b的类型,即base指示),但是由于析构函数不是虚拟的,因此您忘记了销毁derived首先。这导致发生可怕的事情(可能是某种堆栈损坏?)。修复它:


0
投票

[您不能在c ++中将其作为直接向量-不同的派生类具有不同的大小,因此,当复制构造函数将元素放置在数组中时,您将得到切片(经典对象切片)。

© www.soinside.com 2019 - 2024. All rights reserved.