我是C ++的新手。对于“新”系列来说,它究竟意味着什么?例如:
UnicodeStringList* tmp = new UnicodeStringList;
// where UnicodeStringList is typedef to std::list<UnicodeString>
当你“新”某事时,你必须知道你需要它有多大,对吧?所以,当我 使用赋值构造函数来复制一个对象,计算机将如何知道应该在堆上分配多少内存?例如:
*tmp = another_string_list;
另一个_string_list被复制到堆内存中新的UnicodeStringList中,但我最初从未指定堆内存应该有多大。并且编译器不知道another_string_list有多大,所以有多少内存进入堆?
我很困惑,希望我已经指明了我的问题,所以有人可能理解我,但我不确定。
请帮忙
谢谢,
儒略
答案 0 :(得分:5)
向其添加元素时,std::list
的大小不会更改。我将使用std::vector
因为示例更简单,但同样的概念适用:std::vector
包含指向数组的指针,根据需要动态调整大小以包含元素。指向数组的指针大小不会改变(它是一个指针的大小),即使它指向的数组发生了变化
答案 1 :(得分:3)
“new”所做的只是分配足够的空间来存储std::list
的所有成员变量。任何可能需要做的额外事情都是std::list
的业务,它应该自己处理(通过它的构造函数和析构函数)。
答案 2 :(得分:2)
当你“新”某事时,你必须知道你需要它有多大,对吗?
不完全是。至少,不是你想的那样。
当您new
原始数组时,您当然必须提供数组中的元素数。但是std::list
,std::vector
等不是原始数组。
以std::list
为例:从外部,你可以把它想象成包含你投入的任何内容。但是,详细地说,它是一个直接只包含指针的对象。这些指针指向它在堆上分配的其他对象(使用new
)。因此std::list
本身的实例总是大小相同,但是当你向它添加更多内容时,最终会在堆上的其他地方分配更多的东西来管理它。
这也是为什么你可以使用列表作为堆栈分配的局部变量,并且无法将任意数量的项目推入其中。
UnicodeStringList MyList;
MyList.push_back(item1);
MyList.push_back(item2);
无需new
。该列表安排自己的内部(堆分配)簿记以容纳我的项目,并且您想要添加它。
当一个列表A分配给列表B时,列表A中的所有项目(以及任何内部管理的簿记对象)将被复制到新堆分配的项目中,并提供给列表B进行管理。
答案 3 :(得分:1)
你实际上必须知道有多大东西的唯一地方就是堆栈。堆栈必须以非常静态的方式增长,以取悦编译器。但是,堆没有这样的约束。
当你new
某事时,你在堆上分配它。因此,它可以是任何尺寸。您应该感到惊讶的是,集合可以也在堆栈上分配。这是因为无论集合包含什么,它的大小都是不变的。相反,它包含堆的信息(如指针),其中分配的大小必须是变体。
答案 4 :(得分:1)
当您new
和对象时,您将获得该对象处于初始状态所需的内存。但是,您需要意识到一个类在处理其内部状态方面可以实现相当多的复杂性。
特别针对您的问题,类(在您的情况下为list<>
)本身可以在其操作过程中动态分配和释放内存。这就是你的list
集合将要做的事情 - 当一个项目被添加到列表中时,它将为该项目分配内存并执行管理该新项目所需的任何内务管理,通常使用指针或智能指针对象。因此list<>
对象使用的内存可能会发生变化,但“核心”列表对象本身的大小与最初分配时的大小相同。
答案 5 :(得分:0)
您可能想要查找新功能。它将它放在堆内存而不是堆栈内存上。这样,当你失去范围时,它不会消失。它与已知尺寸无关。 您可能会将此与数组混淆,当您为数组分配内存时,您需要知道其大小,并且通常需要更新它。