C++ 类成员中T[n]与T*样式数组的含义

C++ 类成员中T[n]与T*样式数组的含义,c++,memory,containers,C++,Memory,Containers,我正在实现一个用于长期内存管理的超级简单容器,该容器将包含一个数组 我想知道,下面这两种方法的实际含义是什么 template<class T, size_t C> class Container { public: T objects[C]; }; 模板 类容器 { 公众: T对象[C]; }; 以及: 模板 类容器 { 公众: 容器(尺寸\u t盖) { 此->对象=新的T[cap]; } ~Container() { 删除[]此->对象; } T*物体; }; 请记

我正在实现一个用于长期内存管理的超级简单容器,该容器将包含一个数组

我想知道,下面这两种方法的实际含义是什么

template<class T, size_t C>
class Container
{
public:
   T objects[C];
};
模板
类容器
{
公众:
T对象[C];
};
以及:

模板
类容器
{
公众:
容器(尺寸\u t盖)
{
此->对象=新的T[cap];
}
~Container()
{
删除[]此->对象;
}
T*物体;
};

请记住,这些都是最简单的示例,我没有考虑存储容量、虚拟大小等问题。

如果在编译时知道容器的大小,如第一个示例中所示,您应该更好地使用。例如:

template<class T, size_t C>
class Container
{
public:
   std::array<T, C> objects;
};
模板
类容器
{
公众:
std::数组对象;
};
这有着重要的优势:

  • 您可以通过获取对其元素的访问权限,这会在编译时自动检查访问权限是否在范围内
  • 您有用于
    Container::objects
    的迭代器,因此可以使用的所有例程
第二个例子有一些重要的缺点:

  • 访问元素时不能强制执行边界检查:这可能会导致错误
  • 如果构造函数中的
    new
    抛出?你必须妥善处理这个案子
  • 您需要一个合适的复制构造函数和赋值运算符
  • 您需要一个
    virtual
    析构函数,除非您确定没有人从该类派生,请参阅

如果在编译时知道容器的大小(如第一个示例中所示),则可以使用。

避免所有这些问题,最好使用。例如:

template<class T, size_t C>
class Container
{
public:
   std::array<T, C> objects;
};
模板
类容器
{
公众:
std::数组对象;
};
这有着重要的优势:

  • 您可以通过获取对其元素的访问权限,这会在编译时自动检查访问权限是否在范围内
  • 您有用于
    Container::objects
    的迭代器,因此可以使用的所有例程
第二个例子有一些重要的缺点:

  • 访问元素时不能强制执行边界检查:这可能会导致错误
  • 如果构造函数中的
    new
    抛出?你必须妥善处理这个案子
  • 您需要一个合适的复制构造函数和赋值运算符
  • 您需要一个
    virtual
    析构函数,除非您确定没有人从该类派生,请参阅

除了@francesco的答案外,您还可以使用。

来避免所有这些问题:

第一个示例

在第一个示例中,
容器
包含一个
C样式数组
。如果在堆栈上创建了
容器
的实例,那么数组也将在堆栈上。您可能想阅读(或类似内容)。因此,在堆栈上进行分配可能有好处,但您必须小心指定给数组的大小(
size\t C
),以避免堆栈溢出

您应该考虑使用<代码> STD::数组< /C> > < /P> 第二个示例

这里您持有类型为
T
的指针,该指针指向在堆上分配的
C样式数组
(无论是在堆栈上还是在堆上分配
Container
的实例)。在这种情况下,您不需要在编译时知道大小,这在许多情况下都有明显的优势。此外,对于
size\u t C
,可以使用更大的值

您应该考虑使用<代码> STD::vector < /代码> .< 进一步研究


要进一步研究,请阅读堆栈与堆分配/性能的对比,以及。

除了@francesco的答案之外:

第一个示例

在第一个示例中,
容器
包含一个
C样式数组
。如果在堆栈上创建了
容器
的实例,那么数组也将在堆栈上。您可能想阅读(或类似内容)。因此,在堆栈上进行分配可能有好处,但您必须小心指定给数组的大小(
size\t C
),以避免堆栈溢出

您应该考虑使用<代码> STD::数组< /C> > < /P> 第二个示例

这里您持有类型为
T
的指针,该指针指向在堆上分配的
C样式数组
(无论是在堆栈上还是在堆上分配
Container
的实例)。在这种情况下,您不需要在编译时知道大小,这在许多情况下都有明显的优势。此外,对于
size\u t C
,可以使用更大的值

您应该考虑使用<代码> STD::vector < /代码> .< 进一步研究


为了进一步研究,在堆栈上读取堆分配/性能,并且.< /p>我将诚实地忘记这一点,因为您用C++标记了这个问题。使用std::vector和std::array。如果您的容器大小在编译时已知,则选择第一个,否则选择第二个。在这两种情况下,按照@mfnx的建议,选择

std::array
std::vector
。这感觉有点像一个短文式的问题。它可能有点宽。我会诚实地忘记这一点,因为你用C++来标注这个问题。使用std::vector和std::array。如果您的容器大小在编译时已知,则选择第一个,否则选择第二个。在这两种情况下,按照@mfnx的建议,选择
std::array
std::vector
。这感觉有点像一个短文式的问题。它可能有点宽。很好,我不知道std::array,它似乎指向了我要寻找的方向。如果构造函数中有新的抛出,数组就不会被创建。您可能有分配错误,但您可以