作为一名 Java 开发人员,我有以下 C++ 问题。
如果我有类型 A 的对象并且我想将它们的集合存储在一个数组中, 那么我应该只存储指向对象的指针还是存储对象本身更好?
在我看来,存储指针更好,因为: 1) 通过将对象的指针设置为 null,可以很容易地删除对象 2) 节省空间。
最佳答案
指针还是对象?
在 C++ 中不能将引用放在数组中。您可以制作一个指针数组,但我仍然更喜欢容器和实际对象而不是指针,因为:
- 没有机会泄漏,异常安全更容易处理。
- 它并没有减少空间——如果你存储一个指针数组,你需要对象的内存加上指针的内存。
我唯一提倡将指针(或智能指针会更好)放入容器(或数组,如果必须的话)是当您的对象不可复制可解释和可分配时(容器的要求,指针总是满足this) 或者你需要它们是多态的。例如
#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
}
如果你想走这条路boost pointer containers您可能会感兴趣,因为他们会为您完成所有艰苦的工作。
从数组或容器中移除。
分配 NULL
不会导致容器/数组中的指针减少,(它也不处理 delete
),大小保持不变相同,但现在有些指针您不能合法取消引用。这会使您的其余代码以额外的 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));
我真的不喜欢在一般的指针序列中允许 NULL
的想法,因为您很快就会将所有实际工作埋没在一系列条件语句中。另一种方法是 std::vector
提供了一个采用迭代器的 erase
方法,因此您可以这样写:
v2.erase(v2.begin());
删除第一个或 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;
}
保留顺序需要一系列洗牌而不是一次交换,这很好地说明了 std::vector
面临的删除的复杂性。当然,通过这样做,您只是重新发明了一个相当大的轮子,与免费的标准库容器相比,它的实用性和灵 active 要差得多!
关于c++ - 数组 : Storing Objects or References,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8068950/