作为Java开发人员,我有以下C++问题.
如果我有类型A的对象并且我想将它们的集合存储在数组中,那么我应该只存储指向对象的指针还是更好地存储对象本身?
在我看来,最好存储指针,因为:1)通过将其指针设置为null,可以轻松删除对象2)节省空间.
您不能在C++中将引用放入数组中.你可以创建一个指针数组,但我仍然更喜欢容器和实际对象而不是指针,因为:
我主张在容器(或数组,如果你必须)中放置指针(或智能指针会更好)的唯一时间是你的对象不是可复制的可构造和可分配的(对容器的要求,指针总是满足这个)或你需要它们是多态的.例如
#include <vector>
struct foo {
virtual void it() {}
};
struct bar : public foo {
int a;
virtual void it() {}
};
int main() {
std::vector<foo> v;
v.push_back(bar()); // not doing what you expected! (the temporary bar gets "made into" a foo before storing as a foo and your vector doesn't get a bar added)
std::vector<foo*> v2;
v2.push_back(new bar()); // Fine
}
Run Code Online (Sandbox Code Playgroud)
如果你想沿着这条道路向下推进指针容器可能会引起人们的兴趣,因为它们会为你完成所有艰苦的工作.
分配NULL不会导致容器/数组中的指针数量减少(它也不会处理delete),大小保持不变,但现在有指针无法合法取消引用.这使得代码的其余部分以extra if语句的形式变得更加复杂,并禁止以下内容:
// need to go out of our way to make sure there's no NULL here
std::for_each(v2.begin(),v2.end(), std::mem_fun(&foo::it));
Run Code Online (Sandbox Code Playgroud)
我真的不喜欢NULL在一般的指针序列中允许s 的想法,因为你很快就会把所有实际工作都埋没在一系列条件语句中.另std::vector一种erase方法是提供一个采用迭代器的方法,以便您可以编写:
v2.erase(v2.begin());
Run Code Online (Sandbox Code Playgroud)
删除第一个或v2.begin()+1第二个.std::vector由于时间的复杂性,没有简单的"擦除第n个元素"方法- 如果你正在进行大量的擦除,那么还有其他容器可能更合适.
对于阵列,您可以使用以下方法模拟擦除:
#include <utility>
#include <iterator>
#include <algorithm>
#include <iostream>
int main() {
int arr[] = {1,2,3,4};
int len = sizeof(arr)/sizeof(*arr);
std::copy(arr, arr+len, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// remove 2nd element, without preserving order:
std::swap(arr[1], arr[len-1]);
len -= 1;
std::copy(arr, arr+len, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// and again, first element:
std::swap(arr[0], arr[len-1]);
len -= 1;
std::copy(arr, arr+len, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
保留顺序需要一系列shuffle而不是单个swap,这很好地说明了擦除std::vector面的复杂性.当然,通过这样做,你只是重新创造了一个相当大的轮子,比标准的库容器免费为你做的更有用和灵活!