c++ - 数组 : Storing Objects or References

标签 c++

作为一名 Java 开发人员,我有以下 C++ 问题。

如果我有类型 A 的对象并且我想将它们的集合存储在一个数组中, 那么我应该只存储指向对象的指针还是存储对象本身更好?

在我看来,存储指针更好,因为: 1) 通过将对象的指针设置为 null,可以很容易地删除对象 2) 节省空间。

最佳答案

指针还是对象?

在 C++ 中不能将引用放在数组中。您可以制作一个指针数组,但我仍然更喜欢容器和实际对象而不是指针,因为:

  1. 没有机会泄漏,异常安全更容易处理。
  2. 它并没有减少空间——如果你存储一个指针数组,你需要对象的内存加上指针的内存。

我唯一提倡将指针(或智能指针会更好)放入容器(或数组,如果必须的话)是当您的对象不可复制可解释和可分配时(容器的要求,指针总是满足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/

相关文章:

围绕基本类型的 C++ 类包装器

c++ - 通过运算符重载访问类属性的快捷方式

c++ - 带有 C++11 的 Visual Studio 2008

c++ - 测试夹具中的设置与构造函数

C++ 调用不同的类构造函数,避免切换

c++ - 当 noexcept 函数尝试在 gcc 或 clang 中调用非 noexcept 函数时启用警告

c++ - 为什么理解这个递归示例如此难以凭直觉?

C++ 与 git 和 CMake : How to build submodules with specific parameters?

c++ - 使用多重继承来区分使用角色?

c++ - #ifndef 为什么要使用类名以外的其他名称?