C++ 我应该在类中使用指向集合的指针吗?

C++ 我应该在类中使用指向集合的指针吗?,c++,C++,假设我有一个类,我希望它有一个deque和一个向量。为这些集合使用指针的优点和缺点是什么 class A { unique_ptr<deque<t>> a; deque<t>* b; deque<t> c; unique_ptr<vector<t>> x; vector<t>* y; vector<t> z; } A类 { 独特的ptr a; 德克*b; 德克c; 独特的

假设我有一个类,我希望它有一个deque和一个向量。为这些集合使用指针的优点和缺点是什么

class A 
{
  unique_ptr<deque<t>> a;
  deque<t>* b;
  deque<t> c;

  unique_ptr<vector<t>> x;
  vector<t>* y;
  vector<t> z;
}
A类
{
独特的ptr a;
德克*b;
德克c;
独特的ptr x;
向量*y;
向量z;
}

我不知道什么时候该使用,因为我很少看到类中用于集合的指针。

如果需要实际的动态资源,请使用
std::unique\u ptr
std::shared\u ptr

如果您需要引用您不拥有的对象(即,您不会销毁/取消分配它),请使用原始指针或引用。如果需要将指针“重新指向”其他对象,请使用指针而不是引用


否则,按值(即非动态)成员/变量使用。

动态分配通常意味着对象应具有编程控制的生存期。这意味着,当使用指针和动态分配时,您现在可以控制在程序中创建和销毁对象的时间,而不是通常范围内的生命期

添加不必要的间接级别可能有害,但不会为程序添加任何有用的内容。它还可能有维护成本和性能成本,在某些情况下还可能有安全成本

但在某些情况下,这可能很有用,因为您实际上需要这种级别的间接寻址。例如,程序的某些部分可能会监视集合中的新值,而另一部分则在其中添加新值。您需要共享资源,答案可能是指针和动态分配

即使这样,我也会动态分配一个包含集合的类,而不是直接分配集合。具有名称和操作的类传递含义并公开精确的操作。简单向量更为通用,它的含义必须从使用它的代码中派生出来

通常不会动态分配的另一个原因是,使用集合时唯一需要的属性是它们的值。其中的元素,而不是集合本身的标识

为这些集合使用指针的优点和缺点是什么

class A 
{
  unique_ptr<deque<t>> a;
  deque<t>* b;
  deque<t> c;

  unique_ptr<vector<t>> x;
  vector<t>* y;
  vector<t> z;
}
指针可以指向存储在包含指针的对象之外的其他位置的对象(如集合)

与在类中存储对象(如集合)相比,这是优点还是缺点取决于用例

我应该在类中使用指向集合的指针吗

这取决于类的用例。如果需要指向某个对象,请使用指针。如果不需要,那么最好不要使用指针

将对象(如集合)存储在成员中使对象生存期考虑变得简单,因为成员的生存期与超级对象的生存期绑定。添加间接(通过指针)会带来复杂性,因为存储在别处的对象不一定共享指针的生命周期


所有这些通常都适用于所有对象,包括但不限于容器。

“我很少看到用于集合的指针”-我想这就是你的答案。在大多数情况下,避免使用指针。在某些情况下,您需要它们,但您可以编写大量根本不使用它们的代码。除了转角情况(空,可能很短)之外,
std::vector
std::dequeue
都在实现中使用基于堆的备份存储。请注意,
sizeof(std::vector)
是常量,无论它存储了多少个元素。因此,在不使用指针的情况下直接使用它们,因为如果使用指针,您所做的只是添加另一个堆操作(以及丢失局部性)。问问自己,这样做能带来什么好处,以及是否值得付出代价。@BitTickler:“小字符串优化”在大多数标准集合中,尤其是在
std::vector
中,是非法的。在集合中内联存储单个元素时,您根本无法满足
std::swap
的语义。第一部分可以提到,包含共享动态对象的
deque
与作为共享对象的
deque
之间存在差异。我从未见过一个指向标准容器(除了与其他容器极为不同的
std::array
)是有意义的。@我想到了两个可能的想法,原因如下:标准容器本身以某种方式驻留在共享内存中,以及一些具有严重堆栈大小限制的系统中,假设
sizeof(container)>sizeof(uintpttr\t)
@BitTickler我也能想象这样的情况,但我从未在现实中见过。如果~2个指针的内存足以证明额外的间接寻址和额外的动态分配(总内存使用量和分配数量)是合理的,则堆栈大小限制必须非常严格。在这种有限的情况下,我会惊讶地发现动态内存首先是可用的。如果我是在这样的情况下,我可能会考虑实现一个习惯>代码>:我::向量< /代码> <代码> siZeof(My::vector)== sieof(UntPrTrt)< /C>。