首页 > 解决方案 > 创建对象以添加到指针数组的函数

问题描述

delete对新对象的使用和创建有点困惑。假设我有一个类,它在数组中存储指向其他对象的指针:

#include <array>
#include "someObject.hpp"
class someContainer() {
    std::array<someObject*, 10> objects;
    void set_object(int n);
}

在不涉及使用智能指针或其他包装器someObjectset_object函数中创建和存储实例的最佳方法是什么。

例如,我相信...

void someContainer::set_object(n) {
    // Some check that 0 < n < 9
    ...
    //=====
    someObject object* = &someObject(constructor_param);
    objects[n] = object;
}

... 将导致未定义的行为,因为object' 引用的析构函数在函数退出时被调用。

那么,正确的方法会是这样吗?

void someContainer::set_object(n) {
    // Some check that 0 < n < 9
    ...
    //=====
    someObject object* = new someObject(constructor_param);
    objects[n] = object;
}

void someContainer::~someContainer() {
    int len = objects.size
    for (int i=0; i < len; i++) {
        delete objects[i];
    }

或者我在某处缺少未定义的行为?(另外,我认为不应该在遍历数组的同时还从中删除对象,这就是我使用len索引的原因。这是真的吗?)我在这里问是因为事情可以编译并且看起来运行良好,但我真的很难知道。

标签: c++new-operator

解决方案


这是内存管理中的一个重要问题:谁拥有分配的值,即谁负责释放它。如果你打电话

object[n] = new someObject(constructor_param);

并且已经有一个对象存储在那里,旧对象将保留在堆上的某个位置,可能没有任何指向它的指针,所以它永远不能再次被释放。

您可能希望您的二传手看起来像这样:

someObject *someContainer::set_object(n) {
    // Some check that 0 < n < 9
    ...
    //=====
    someObject *previous = objects[n];
    objects[n] = new someObject(constructor_param);
    return previous;
}

向函数的用户发出他需要处理前一个对象的信号,要么delete立即处理,要么将其存储在某个地方。

此外,您可以完全自由地delete使用常规循环中的对象:请记住,您只是释放数组元素指向的对象,而根本不会更改数组。


推荐阅读