【问题标题】:Appending struct by reference to an array in C++通过引用 C++ 中的数组来附加结构
【发布时间】:2021-08-12 16:53:32
【问题描述】:

如何在 C++ 中实现通过引用将结构实例附加到数组的函数?这样在将存储在变量中的结构附加到数组后,可以进一步使用该变量来更改数组的实例。

伪代码:

struct St{
 int x
}

St* arr;
St a = {0};
append a to arr;
a.x = 1;
//expecting arr[0].x = 1

这是带有电影示例的 C++ 代码(请参阅描述问题的 cmets):


struct Film{
    int id;
    char* name;
};

void add_film(Film *&films, int &size, Film &film){
    if (size == 0)
        films = new Film[1];
    else
    {
        Film *tmp = new Film[size + 1];
        for (int i = 0; i < size; ++i)
        {
            tmp[i] = films[i];
        }
        delete[]films;
        films = tmp;
    }
    films[size] = film;
    film = films[size]; //how to reassign passed film object to a new object in array?
    size++;
}

int main(){
    Film *films = nullptr;
    int size = 0;
    Film film = {1, "Name1"};
    add_film(films, size, film);
    film.name = "Name2";
    std::cout << films[0].name;  //output: "Name1", expected: "Name2"
}

【问题讨论】:

  • 首先,不要使用new/delete,而是使用标准类,例如std::vector 在你的情况下。其次,为什么不反过来呢? IE。首先追加/分配对象到列表,然后获取它的引用?
  • 这对于给定的类型是不可能的。可以接近的方法是使用一组电影指针(或更好的std::unique_ptr&lt;Film&gt;s),这将允许您返回对新Film 对象的引用,即使数组增长,该对象也保持不变。我强烈建议创建一个class/struct 来管理电影数据,但这将是处理释放内存的常用方法;请注意,最后分配的数组永远不会被您的代码释放,如果您计划在单个程序中使用多个电影列表(关键字内存泄漏),这是一件坏事
  • @fabian 可以,使用std::reference_wrapper,但通常不需要。

标签: c++ arrays function pass-by-reference


【解决方案1】:

在 C++ 中通过引用数组来附加结构

这样做有两个问题:

  1. C++ 中不能有引用数组。
  2. 无法追加到数组。数组的大小是一个常数。无法添加或删除元素。

您尝试的解决方案的一个问题是您有一组电影,而不是一组引用。这并不奇怪,因为上面描述的问题 1 指出没有引用数组这样的东西。然而,解决方案很简单:使用指针而不是引用。从技术上讲,您可以改用引用包装器,但指针通常更简单。

您基本上已经找到了 2. 的解决方案。您正在做的是创建一个新数组,将旧数组中的旧元素复制到新数组中,然后销毁旧数组。总的来说,这是一种很好的方法,但是这种简单的实现存在许多问题:

  • 裸拥有的指针不安全且难以使用。
  • 在每次追加时重新分配和复制整个数组非常昂贵。

前者可以通过使用 RAII 习语来解决,后者可以通过将对象的存储与对象的创建分开来解决,并通过一个常数因子即几何增长来解决。不过,没有必要实现这样的 RAII 容器,因为标准库已经涵盖了您。它叫做std::vector

结论:您可以使用std::vector&lt;Film*&gt;

【讨论】:

  • 感谢您的回答。我的项目中不允许使用std::vector :) 我可以更改我的add_film 函数,以便它返回新创建的数组结构实例,以便我可以像Film film1 = add_film(...) 一样使用它一行而不是使用两个命令add_film(...); Film film1 = films[0]?声明函数返回类型 Film&amp; 并返回 return films[size] 不起作用。谢谢
猜你喜欢
  • 2020-12-07
  • 2012-01-04
  • 2013-05-12
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多