创建对象的动态数组

Create dynamic array of objects

本文关键字:数组 动态 创建对象      更新时间:2023-10-16

我想创建一个特定对象的动态数组,该数组也支持向数组添加新对象。

我正在尝试解决这个问题,作为我课程练习的一部分。在本练习中,我们不应该使用 std::vector .

例如,假设我有一个名为 Product 的类并声明了一个指针:

Products* products;

那么我想支持以下内容:

products = new Product();
/* code here... */
products[1] = new Product(); // and so on...

我知道当前的语法可能会导致访问冲突。我事先不知道数组的大小,因为它可以在整个程序中发生变化。

问题是:

  1. 没有向量怎么写?

  2. 我必须使用双指针(二维)吗?

  3. 每次我想添加一个新对象时,我是否必须将数组复制到新数组(大小为 +1),然后删除数组?

  1. 你不应该在没有std::vector的情况下写这个.如果您出于某种原因需要这样做,则每次调整大小的复制都是迄今为止最简单的选择。
  2. 我看不出这会有什么帮助。(即没有)
  3. 如上所述,如果您无法使用std::vector,这是迄今为止最简单的方法。其他一切都将(部分)重新发明一个标准库容器或另一个,这很难。
  1. 您必须使用自己的内存内存管理,即更具体地说,解决您的其他(相关)问题:

  2. 否,如果您有一个连续分配的内存块,您的数据所在的位置。

  3. 是的,如果 2. 是您想要的实现方法。但是,如果您不想使用大内存块,则必须使用(双)链表,它不需要您每次都复制整个数组。

我看到人们已经回答了你的具体问题,所以我会回答一个更笼统的答案。

您必须自己实现一种方法来做到这一点,但是您可以使用许多抽象数据类型,据我所知,最简单的是链表,如下所示:

class ProductNode
{
    public:
        ProductNode() : _data(NULL), _next(NULL)
        {
        }
        void setProduct(Product* p); //setter for the product pointer
        {
            this->_data = p;
        }
        Product getProduct(); //getter for the product pointer
        {
            return *(this->_data);
        }
        void addNext(); //allocate memory for another ProductNode in '_next'
        {
            if(!next)
            {
                  this->_next = new ProductNode();
            }
        }
        ProductNode* getNext(); //get the allocated memory, the address that is in '_next'
        {
             return this->_next;
        }
        ~ProductNode(); //delete every single node from that node and forward, it'll be recursive for a linked list
    private:
        Product* _data;
        ProductNode* _next;
}

声明一个头变量并从那里开始。当然,这里的大多数功能都应该以其他方式实现,它被快速编码,因此您可以看到此作业所需的基础知识。

这是一种方式。您也可以创建自己的数据类型。或者使用其他一些数据类型来抽象数据。

你可能应该做的(即我相信你应该做的)是编写你自己的类来表示一个动态数组(即你要重新发明std::vector的一部分。
尽管这里的许多人说,这是一个值得的练习,应该成为正常计算机科学课程的一部分。

  1. 使用动态分配的数组,该数组是类的成员。
  2. 如果您使用的是动态分配的Product*数组,您将存储一个Product**,所以是的,在某种程度上。但是,没有必要为功能本身设置"双指针"。
  3. 从技术上讲,没有 - 您可以分配超过必要的资源,并且仅在空间不足时才重新分配和复制。这就是vector为提高其时间复杂度所做的工作。
    不过,扩展每个元素是一个很好的开始方式,您以后可以随时更改策略。
    (先获得简单的工作方法,如果需要,请花哨。

最简单的方法是首先实现一个int数组(或其他一些基本数字类型)并确保它有效,然后更改内容的类型。

我想

"产品*产品"的意思是"产品"是一个类似矢量的容器。

1) How can I write it without vectors?

作为链表。实例化"产品产品"将为您提供一个空的链接列表。重写运算符 [] 将插入/替换列表中的元素。因此,您需要扫描列表以找到正确的位置。如果在找到正确的位置之前缺少多个元素,则可能需要在元素之前附加这些"中性"元素。如果您计划覆盖运算符 [] 来处理元素的添加,则通过"产品 *产品"这样做是不可行的,除非您声明"产品产品"

2) Do I have to use double pointers (2-dimension)?

这个问题缺乏精确性。如"typedef Product *Products;",然后是"Products *Products" ?只要您在"产品"和"产品"之间保持"*",就无法覆盖 operator[] 来处理元素的添加。

3) Every time I want to add a new object, do I have to copy the array to the new array (with +1 size), and then delete the array?

如果你坚持使用数组,你可以使用 O(log2(n)) 时间重新分配,只需增加两倍的数组大小(据说你有一个零终端或嵌入了一个计数)。或者只是使用链表来避免在添加元素之前复制所有元素。