指针数组

3

如何获得一个指向对象(类)的指针数组?

我需要动态分配它们的空间,数组的长度在运行时才确定。有人可以解释并告诉我如何定义它吗?如果能够解释它的工作原理,那就太好了 :)


指向特定类或从单个父类派生的类的指针,还是任何类? - Joseph Mansfield
可变长度数组(VLA)是非标准编译器扩展。它们被添加到C99规范中,但永远不会被添加到C++规范中。它们之所以能够工作,是因为intel/gnu/microsoft实现的编译器扩展。只需使用向量,这就是它们的作用。 - Brian Gianforcaro
我并不是在要求可变长度数组,我说的是数组的长度直到运行时才能确定。那么这样算作可变长度数组吗? - akif
4个回答

15

请使用std::vector,它是专门设计用于动态调整大小的集合。

#include <vector>
// ...
std::vector<Class*> vec;
vec.push_back(my_class_ptr);
Class* ptr = vec[0];

2
一个指针向量如果在使用STL算法时会有很多泄漏的机会。尽可能使用对象向量而不是指针向量。 - KJAWolf
1
@KJAWolf:你能举几个在使用std::vector<T*>时会导致内存泄漏的STL算法的例子吗? - Evan Teran
1
或者一个 boost::ptr_vector<Class> - Martin York
2
他说机会泄漏,而不是算法本身固有泄漏。因此,例如,std::set_difference会为您的向量中的一些(但不是全部)指针创建别名。这为程序员提供了一个很好的机会来错误地管理资源,从而创建泄漏。在左侧输入智能指针。 - Steve Jessop

10

你可以使用指向指针的方式来实现这个功能。

MyClass ** arrayOfMyClass = new MyClass*[arrayLengthAtRuntime];
for (int i=0;i<arrayLengthAtRuntime;++i)
    arrayOfMyClass[i] = new MyClass(); // Create the MyClass here.

// ...
arrayOfMyClass[5]->DoSomething(); // Call a method on your 6th element

基本上,您正在创建一个指向内存中引用数组的指针。第一个new分配了这个数组。循环将每个MyClass实例分配到该数组中。

如果您使用std::vector或另一个可以随意增长的容器,则此过程会变得更加容易,但是如果您想自己管理内存,则上述方法也可行。


1
如果我错了的话(已经有一段时间了),但别忘了在完成后调用delete[]来释放。 - John MacIntyre
我不认为他展示了代码,让你删除数据 - 假设数组的生命周期超过单个函数调用。此外,调整大小很麻烦。因此建议使用向量/列表集合类。 - Kieveli
如果我使用向量,我需要调用delete吗?我将动态分配内存。 - akif
3
Manzoor,只有在使用了new之后才能使用delete。你不会使用new创建一个vector,因此不要使用delete来销毁它。如果你使用new来分配存储在vector中的元素,那么就应该使用delete来销毁它们。 - Rob Kennedy
2
你想要一个指向对象的指针数组。这需要一个指向指针的指针——第一个指向数组(在内存中),其中数组的每个元素都指向你的类。 - Reed Copsey
1
@Kievelli:我完全同意 - 我会使用向量/列表等形式,但我仍然认为了解背后发生的事情非常有价值,尤其是对于这种情况。 - Reed Copsey

4
使用boost::ptr_vector,避免数组和指针的困扰:
boost::ptr_vector<animal> vec;
vec.push_back( new animal );
vec[0].eat();

您可以动态添加元素,无需担心删除它们。

如果Boost不是一个选项(不幸的是,无论我在哪里工作C++代码,由于某些愚蠢的原因,这似乎都是情况),但TR1是 - 例如,您正在使用最新的g++版本或VC++2008 SP1,则std::vector<std::tr1::shared_ptr<animal> >也可以解决问题。 - Pavel Minaev

3

我还不能编辑或评论,所以我只能用答案来发布:Reed Copsey所说的没错,但需要有一个修正。当您访问指针数组的元素时,您需要像这样访问成员:

MyClass ** arrayOfMyClass = new MyClass*[arrayLengthAtRuntime];
for (int i=0;i<arrayLengthAtRuntime;++i)
    arrayOfMyClass[i] = new MyClass(); // Create the MyClass here.

// ...
arrayOfMyClass[5]->DoSomething(); // Call a method on your 6th element

我经常使用这种方法来实现自己的动态大小数组(就像std::vector一样),主要是因为我有“非此即彼”综合症,同时也因为我喜欢根据我的特定用途进行定制。


1
你对 std::vector 有“非此即彼”症候群吗?如果是的话,你应该考虑自己编写一个 C++ 编译器,并且可能还要构建自己的 CPU。 - Mehrdad Afshari
这部分原因是因为在我了解std::vector的存在之前,我学会了编写自己的向量,现在这只是一种习惯 ;) - Daniel Bingham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接