【问题标题】:Deleting dynamic objects with a destructor? C++使用析构函数删除动态对象? C++
【发布时间】:2013-05-21 05:18:46
【问题描述】:

我在整个程序中有一些对象面临类似问题。一个例子:

我有一个 Image 类:

class Image
{
public:
    Image();
    Image(const Image& copy);
    ~Image();

    void loadimage(string filename);
    void saveimage(string filename);
    Image superimpose(const Image& ontop, Color mask);

    int getwidth();
    int getheight();
    Image operator=(const Image&);

protected:    
    Color** pixels;
    int width;
    int height;
    ImageLoader* loader;
};

它有一个拷贝构造函数:

Image::Image(const Image& copy)
{
    width = copy.width;
    height = copy.height;
    loader = copy.loader;

    pixels = new Color*[height];
    for(int i = 0; i < height; i++)
    {
        pixels[i] = new Color[width];
    }

    for(int h = 0; h < height; h++)
    {
        for(int w = 0; w < width; w++)
        {
            pixels[h][w] = copy.pixels[h][w];
        }
    }
}

颜色是一个结构体:

struct Color
{
    unsigned int r;
    unsigned int g;
    unsigned int b;
};

我担心的是我创建了一个 Color 结构的动态二维数组,但我不确定何时何地删除它。我在我的 Image 析构函数中实现了以下内容,但我不能 100% 确定它是否在做这项工作,我不确定如何检查它是否有效:

Image::~Image()
{
    for(int i = 0; i < height; i++)
    {
        delete[] pixels[i];
    }

    delete[] pixels;
    pixels = NULL;
}

我是否正确实现了内存释放?

【问题讨论】:

  • 最正确的方法是根本不实现它并使用可以为您管理内存的东西。此外,将即将被销毁的东西设置为NULL 是毫无意义的。
  • @chris 所以....我会用什么?你没有提到。
  • 我一般更喜欢封装一维std::vectorMatrix类。

标签: c++ dynamic memory-management


【解决方案1】:

没关系。

两点,可以使用unique_ptrshared_ptr,摆脱自删内存。

其次,我更喜欢使用nullptr0 而不是NULL (尽管它是标准的)。此外,由于容器对象正在销毁,因此您无需将其成员设置为 null。

最好使用std::vector

std::vector<std::vector<Color>> pixels;

...

Image::Image(const Image& copy)
{
    width = copy.width;
    height = copy.height;
    loader = copy.loader;

    pixels.resize(height);
    for (int i = 0; i < height; i++)
    {
        pixels[i].resize(width);
    }

    for(int h = 0; h < height; h++)
    {
        for(int w = 0; w < width; w++)
        {
            pixels[h][w] = copy.pixels[h][w];
        }
    }
}

【讨论】:

  • +1 表示unique_ptr,比这里的vector 更有效。但是shared_ptr 不支持数组。
  • 在这种情况下你将如何实现 unique_ptr?我已经阅读了它们,但我有点困惑。
【解决方案2】:

我是否正确实现了内存释放?

是的。它是正确的。不过你最好把二维动态数组换成vector of vectors,它自己管理内存,更安全,更不容易出错。

【讨论】:

  • 谢谢,如果我无法弄清楚 M M 建议的 unqiue_ptr,我可能不得不这样做。
  • @Noobacode 欢迎您。你可能会在 SO 上找到很多关于 unique_ptr 的帖子。
【解决方案3】:

我发现这里缺少 RAII 以及引发潜在异常的问题,例如 bad_alloc,这将使您的对象处于未定义状态。我会在一个为你管理内存的对象中分配内存,因此当对象超出范围时,它会自行销毁。所述对象还应该提供一个复制构造器,它可以深度复制内存并允许您通过指向第一个字节的指针访问原始数据。 std::vector 具有所有这些属性。

【讨论】:

  • 在您提到之前从未听说过 RAII,谢谢。这是一本好书。
猜你喜欢
  • 2021-04-10
  • 2015-01-10
  • 1970-01-01
  • 2015-12-31
  • 2013-09-30
  • 2013-01-16
  • 2012-02-05
  • 2016-06-14
  • 2013-12-08
相关资源
最近更新 更多