清理 C++ 中的动态对象数组
我对在 C++ 中处理对象数组感到有点困惑,因为我似乎无法找到有关它们如何传递(引用或值)以及它们如何存储在数组中的信息。
我希望对象数组是指向该对象类型的指针数组,但我没有在任何地方找到这样的写法。它们是指针,还是对象本身以数组的形式放置在内存中?
在下面的示例中,自定义类 myClass 保存一个字符串(这会使其大小可变,还是字符串对象保存指向字符串的指针,因此占用一致的空间量。我尝试创建一个动态数组myContainer 中的 myClass 对象。在 myContainer.addObject() 方法中,我尝试创建一个更大的数组,将所有对象与新对象一起复制到其中,然后删除旧对象,我一点也不相信我'。我正在使用析构函数正确清理我的内存 - 我可以在这方面做出哪些改进?
class myClass
{
private:
string myName;
unsigned short myAmount;
public:
myClass(string name, unsigned short amount)
{
myName = name;
myAmount = amount;
}
//Do I need a destructor here? I don't think so because I don't do any
// dynamic memory allocation within this class
};
class myContainer
{
int numObjects;
myClass * myObjects;
public:
myContainer()
{
numObjects = 0;
}
~myContainer()
{
//Is this sufficient?
//Or do I need to iterate through myObjects and delete each
// individually?
delete [] myObjects;
}
void addObject(string name, unsigned short amount)
{
myClass newObject = new myClass(name, amount);
myClass * tempObjects;
tempObjects = new myClass[numObjects+1];
for (int i=0; i<numObjects; i++)
tempObjects[i] = myObjects[i]);
tempObjects[numObjects] = newObject;
numObjects++;
delete newObject;
//Will this delete all my objects? I think it won't.
//I'm just trying to delete the old array, and have the new array hold
// all the objects plus the new object.
delete [] myObjects;
myObjects = tempObjects;
}
};
I'm a bit confused about handling an array of objects in C++, as I can't seem to find information about how they are passed around (reference or value) and how they are stored in an array.
I would expect an array of objects to be an array of pointers to that object type, but I haven't found this written anywhere. Would they be pointers, or would the objects themselves be laid out in memory in an array?
In the example below, a custom class myClass holds a string (would this make it of variable size, or does the string object hold a pointer to a string and therefore take up a consistent amount of space. I try to create a dynamic array of myClass objects within a myContainer. In the myContainer.addObject() method I attempt to make a bigger array, copy all the objects into it along with a new object, then delete the old one. I'm not at all confident that I'm cleaning up my memory properly with my destructors - what improvements could I make in this area?
class myClass
{
private:
string myName;
unsigned short myAmount;
public:
myClass(string name, unsigned short amount)
{
myName = name;
myAmount = amount;
}
//Do I need a destructor here? I don't think so because I don't do any
// dynamic memory allocation within this class
};
class myContainer
{
int numObjects;
myClass * myObjects;
public:
myContainer()
{
numObjects = 0;
}
~myContainer()
{
//Is this sufficient?
//Or do I need to iterate through myObjects and delete each
// individually?
delete [] myObjects;
}
void addObject(string name, unsigned short amount)
{
myClass newObject = new myClass(name, amount);
myClass * tempObjects;
tempObjects = new myClass[numObjects+1];
for (int i=0; i<numObjects; i++)
tempObjects[i] = myObjects[i]);
tempObjects[numObjects] = newObject;
numObjects++;
delete newObject;
//Will this delete all my objects? I think it won't.
//I'm just trying to delete the old array, and have the new array hold
// all the objects plus the new object.
delete [] myObjects;
myObjects = tempObjects;
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
C++ 中的数组是放置在内存中的对象数组。
例如:
数组中的每个项目的大小都是两个整数。
如果您想要一个指针数组,您可以简单地声明一个:
字符串对象具有指向字符串的可变大小部分的指针。所以他们很安全。
事实上,它们是这里重要的一课。与使用字符串类避免过多的内存处理相同,您可以使用向量类来避免处理动态数组的所有麻烦。
对于这种情况,您将这样做作为练习。这里有几个问题:
newObject
需要本地分配,没有new
。这将使代码正确(因为newObject
不是指针,而new
返回指针),并且还可以省去显式处理内存的麻烦。 (更高级地说,这使得代码异常在另一个位置变得安全)myObject
从未初始化。并且您不在构造函数中使用初始化列表。构造函数应该如下所示:代码中的析构函数完全符合其应有的样子。
An array in C++ is an array of objects laid out in memory.
So for example in:
Each item in the array is going to be with a size of two ints.
If you want an array of pointers you can simply declare one:
The string objects have pointers to the variable size part of the string. So they're safe.
In fact they're the important lesson here. Same way you use the string class to avoid excessive memory handling you can use the vector class to avoid all the troubles of handling a dynamic array.
For the case you're doing this as an exercise. Here are a few problems:
newObject
needs to be allocated locally, withoutnew
. This will make the code correct (asnewObject
is not a pointer andnew
returns a pointer) and will also save you the trouble of explicitly handling memory. (On a more advanced note, this makes the code exception safe in one more location)myObject
is never initialized. And you don't use initialization lists in the constructor. The constructor should look like this:The destructors in the code are exactly as they should be.
不,动态数组不是指向该类型的指针数组 - 它是指向第一个元素的指针。这些元素在内存中连续排列,并在数组被
delete[]
编辑时被销毁。因此,您的释放看起来很好 - 您创建了
myClass
对象的动态数组,因此您不必单独删除
它们。仅当您有一个指向(动态分配的)对象的指针数组时,您才需要执行此操作。不过,有两个明确的错误:
这应该是例如:
此外,
myObjects
从未初始化,这意味着它包含垃圾,取消引用/使用它会导致未定义的行为。最后,除非您这样做是为了学习目的,否则只需使用像 std::vector 这样的容器即可为您完成所有工作。
No, a dynamic array is not an array of pointers to that type - its a pointer to the first element. The elements are laid out consecutively in memory and are destroyed when the array is
delete[]
ed.Thus your deallocation looks fine - you create dynamic arrays of
myClass
objects so you don't have todelete
them individually. You would only have to do this if you had an array of pointers to (dynamically allocated) objects.There are two definitive errors though:
This should be e.g.:
Also,
myObjects
is never initialized, which means it contains garbage and dereferencing/using it leads to undefined behaviour.Finally, unless you are doing this for learning purposes, simply use containers like
std::vector
that do all the work for you already.我希望对象数组是指向该对象类型的指针数组,但我没有在任何地方找到这样的写法。它们是指针,还是对象本身以数组的形式放置在内存中?
数组将由对象本身组成。如果你想要一个指针数组,你必须声明:
我假设你习惯 C# 或 Java?在这些语言中,对象只能在堆上分配,并且始终通过引用来访问。在 C++ 中这是可能的,但在 C++ 中你也可以将对象直接放入堆栈中,或者直接构造对象本身的数组。
在下面的示例中,自定义类 myClass 保存一个字符串(这会使其大小可变,还是该字符串对象保存指向字符串的指针,因此占用一致的空间量?
二:字符串对象本身的大小是恒定的,但有一个指向从堆分配的动态大小的缓冲区的指针,
我认为可以通过多种方式编写代码更有效,但它看起来是正确的。
I would expect an array of objects to be an array of pointers to that object type, but I haven't found this written anywhere. Would they be pointers, or would the objects themselves be laid out in memory in an array?
The array will consist of the objects themselves. If you want to have an array of pointer you will have to declare that:
I assume you are used to C# or Java? In those languages objects can only be allocated on heap and are always accessed by referenced. It is possible in C++, but in C++ you can also put objects directly on the stack, or directly construct an array of the objects themselves.
In the example below, a custom class myClass holds a string (would this make it of variable size, or does the string object hold a pointer to a string and therefore take up a consistent amount of space?
Number two: The string object itself is constant in size, but has a pointer to a dynamically sized buffer allocated from the heap.
I think the deallocation looks fine. The code could be written more efficient in various ways, but it looks correct.
尝试测试它,看看会发生什么(是的,这可能是特定于编译器的,但仍然)......
您可以尝试向 myClass 添加一个自定义析构函数(即使您不需要),该析构函数在调用时会增加一个“全局”计数器,然后在删除数组后打印该计数器。
我希望调用每个对象的析构函数。请注意,对象通常“按指针”存储,以允许将继承的对象放入数组中(避免“切片”)。
Try to test it, to see what happens (yes, that may be compiler-specific, but still)...
You could try to add a custom destructor to myClass (even though you don't need one), that increments a "global" counter when called, Then print the counter after deleting the array.
I would expect the destructor of each object to be called. Note that quite often objects are stored "by-pointers" to allow for inherited objects to be put into the array (avoiding "slicing").