0
#include <iostream>

class A {
 public:
  A(int d) : y(d) {}

  int y;
};

int main(void) {
  A d[3] = {A(0), A(1), A(2)};
  std::cout << d[1].y << std::endl;
};

我正在为大学做一个项目。我被指示不要使用对象数组并用我的类的临时对象实例化每个元素 - 所以像上面的代码这样的东西是不可以的。相反,建议我们使用类型数组,A*然后在每个元素上使用 new,以便我们创建一个对象并使每个元素指向它。

所以我们会有这样的事情:

A* d[3];
for (int i=0;i<3;i++)
d[i]=new A(i);

但是,与第一个版本相比,我不太了解实践中的差异。据我了解,在第一个版本中,我们使用构造函数创建了三个临时对象(它们是右值),然后将它们分配给数组。赋值结束后,临时对象被销毁,其值被复制到数组中。在第二个版本中,我们的优点是可以删除d[]指向的内容,但忽略这一点,使用第一种方法的缺点是什么?

编辑:

class B{
public:
A a1[3];
}

假设我的初始定义后面跟着这个(A 不是默认可构造的,这样的事情是不可能的吗?所以在这种情况下,我不能使用对象数组,而是不得不求助于类型的指针数组,A*然后使用new,作为我唯一的度假胜地。

4

3 回答 3

0

1 ) A d[3],它创建一个内置数组(或 C 风格、普通数组、裸数组...),其中包含(三个)类型的元素A,这些元素位于堆栈中(根据您的代码)。

2 ) A* d[3];,它创建一个内置数组,其中包含(三个)指向类型元素的指针A(或者它们应该)。这并不意味着指向的元素是 type A,创建这些元素是开发人员的任务,您可以通过两种方式使用堆栈(如前所述):

A element;
...
d[0] = &element;

或使用堆(使用new/new[]delete/ delete[]):

d[0] = new A;
...
delete d[0];

第二种选择的副作用;您可能指向一个已经被破坏的元素(即元素超出范围),因此可能存在段错误;您可能会丢失指向已分配内存的指针(即指针数组超出范围且分配的内存尚未释放),因此内存泄漏。

但是,一个优点是您可以使用延迟初始化(您无需为不使用的内容付费)。如果您不需要(或指向)A中的对象d[2],为什么要创建它并浪费内存?这里出现了智能指针,它们使您的生活更轻松,允许您仅在需要时分配内存,从而降低 seg 错误(值得一提的std::weak_ptr)、内存泄漏等风险:

    std::unique_ptr<A> d[3];
    d[0] = std::make_unique<A>(); // Call make_unique when you need it


但还是有点讨厌,内置数组很好,但在某些情况下可能会好得多。很难添加或删除元素,迭代,获取大小,访问尾部/头部等......这就是容器非常有用的原因,即std::arraystd::vector(在编译时不必知道它的大小):

std::vector<std::unique_ptr< A> > d(3);
std::array<std::unique_ptr<A,3> > d;
于 2020-11-14T11:48:11.757 回答
0

指针数组 -> 创建对象并将其分配给指针时的内存分配。包含 1 个元素的 1000 个指针数组 = 1x 内存。

对象数组 -> 创建数组时的内存分配。包含 1 个元素的 1000 数组 = 1000x 内存。

于 2020-11-14T10:49:22.277 回答
-1

There are no advantages whatsoever to the following code in C++:

A* d[3];
for (int i=0;i<3;i++)
d[i]=new A(i);

In fact, you shouldn't write it at all.

Your solution with a locally-declared temporary array is valid, but has the significant limitation of requiring that the number of elements in the array be a compile-time constant (i.e., known ahead of time).

If you need to have an array with a dynamic number of elements, known only at run time, then you should use a std::vector, which performs the new allocation automatically. That is the idiomatic way of working with dynamically-allocated arrays in C++.

于 2020-11-14T10:45:43.180 回答