在C ++中使用指向数组中对象的指针是否更好?

时间:2016-03-26 16:28:28

标签: c++ arrays pointers

我正在尝试使用C ++并试图绕过指针。创建对象数组时,创建对象类型或指针数组是否更好?

例如:

from tqdm import tqdm, tqdm_gui if control_char_work_fine(): progress_bar = tqdm else: progress_bar = tqdm_qui Block grid[size];

从我读过的内容来看,我觉得在使用对象时,使用指针来节省内存几乎总是更好吗?最终我将创建一个动态分配的这些对象的2D数组,我想知道是否值得讨厌尝试将它们存储为多维数组中的指针。

注意:我被告知要研究2D向量,当涉及到动态创建它们并分配它们时,我正在努力与这些数组一样多。

提前致谢!

5 个答案:

答案 0 :(得分:0)

我会使用Block grid[size],因为你为什么会创建一个指针数组(我能想到的唯一原因是编译时大小未知的数组)在内存方面,指针有点更昂贵,因为它们的地址和内容被存储(分别在堆栈和堆上)。当你完成它们时,你不能忘记释放它们,否则你会得到内存泄漏。

<小时/> 更好的选择是std::array<Block, size> grid,甚至是std::vector<Block> grid

std::vector就像一个std::array,但是它的动态,没有固定的大小(例如,你可以将它改为运行时)。

答案 1 :(得分:0)

假设这是一个功能,它不会保存&#39;记忆。 一种实现使用更多堆栈存储器。 另一个使用较少的堆栈内存,但使用更多的堆。

这完全使用堆栈:

Block grid[size];

这使用堆栈来存储指向对象的指针。 用于存储对象的内存是堆:

Block* grid[size];

但是,如果这些是全局声明,那么是,这个:

Block grid[size];

可能会浪费内存,因为它是在应用程序的生命周期内分配的,并且无法解除分配/调整大小。

答案 2 :(得分:0)

我认为你在混合某些东西。经典的C-array 指向第一个元素的指针。您所想到的是在调用函数或类似函数时(深度)复制的类很昂贵。这些昂贵的函数参数(字符串,向量和类似函数)最好作为引用(或指针)传递。

'Modern C ++'为您提供了足够的实用程序,如果您不编写自己的容器,则不应自行使用任何分配。您通常使用指针来指向您在上下文中不拥有的内容。我还建议不再使用经典的C阵列。使用

mockResponse

而不是

  mockBackend.connections.subscribe(
    (connection: MockConnection) => {
      connection.mockError(new Error('some error'));
    });

array<Block, size> grid; // compile-time constant size 将尝试进入堆栈。如果编译时不知道Block grid[size]; // compile-time constant size ,则必须在堆上分配内存。 STL将这些堆数组array<>称为

size

堆数组的旧C风格方式是手动分配内存并在不再需要它后释放它。这非常容易出错,除非你知道你做了什么,否则应该避免。

如前所述,普通旧数组(指针)的区别在于调用函数时。在必须传递指针之前,可能是数组的大小

vector

在C ++中,对于大对象,您应该将它们作为引用传递(或使其成为指针),否则您的向量会被深层复制。

vector<Block> grid(size); // runtime variable size
if (grid.size() > 0) 
   cout << grid[0]; // use grid like an array

现在的缺点是,我们对动态和静态数组有不同的签名:

void fancy_old_function(Block* grid, size_t size) // BAD practise
{
    // do things
}

// ...
{
    Block grid[size];
    fancy_old_function(grid, size); // error prone
    ...
    // maybe alot later
    fancy_old_function(grid, 13); // ohoh! 13 < size?
}

对经典C阵列的一个巨大改进是,我们始终隐含地知道数组的大小。

你可以这样打电话给void fancy_new_function(vector<Block>& grid) // GOOD { // do fancy stuff an potentially change grid }

template <size_t N>
void fancy_new_function(array<Block, N>& grid) // GOOD
{
   // do fancy stuff an potentially change grid
}

HTH

答案 3 :(得分:0)

答案更好&#34;取决于你将如何阵列。

如果Block很小(2-8个字节)或者您需要使用 grid 的每个元素,那么最好不要这样做

Block grid [size] ;

几乎在所有情况下。

假设sizeof(Block)&gt; 512并且您不使用网格

的所有元素
  const int size = 10 ;

你可能会更好。

 Block grid [size] ; 

可能最有意义。另一方面,假设

const in size = 2000000 ;

然后

Block *grid [size] ;

更有意义。

答案 4 :(得分:0)

更好是一个品味问题: - )

对于简单的用例,对象数组可能更简单,因为您一次创建并销毁完整数组。它看起来更像C ++惯用语。

我能想到的例外是:

  • 性能原因,创建对象的成本很高。在这里,您只需为最大尺寸的指针创建一个数组,并在需要时创建对象
  • 与派生类的多态性。恕我直言,这是使用指针数组的最佳用例。因为如果您尝试将派生对象复制到其基类中,您将获得对象切片:基类复制将丢失仅存在于派生类中的所有属性。因此,在这种情况下,您创建一个指向基类的指针数组(它甚至可以是抽象的),并使用具体实现填充它。您可以使用基类中的虚方法操作数组中的任何对象。