簡體   English   中英

在堆棧和堆上創建對象數組

[英]Creating array of objects on the stack and heap

考慮以下代碼:

class myarray
{
    int i;

    public:
            myarray(int a) : i(a){ }

}

如何在堆棧上創建 myarray 的對象數組以及如何在堆上創建對象數組?

您可以通過以下方式在堆棧上創建對象數組

myarray stackArray[100]; // 100 objects

在堆上 (或“freestore”):

myarray* heapArray = new myarray[100];
delete [] heapArray; // when you're done

但最好不要自己管理內存。 相反,使用std::vector

#include <vector>
std::vector<myarray> bestArray(100);

向量是一個動態數組,它(默認情況下)從堆中分配元素。 ††


因為您的類沒有默認構造函數,要在堆棧上創建它,您需要讓編譯器知道將什么傳遞給構造函數:

myarray stackArray[3] = { 1, 2, 3 };

或使用向量:

// C++11:
std::vector<myarray> bestArray{ 1, 2, 3 };

// C++03:
std::vector<myarray> bestArray;
bestArray.push_back(myarray(1));
bestArray.push_back(myarray(2));
bestArray.push_back(myarray(3));

當然,你總是可以給它一個默認的構造函數:

class myarray
{
    int i;    
public:
    myarray(int a = 0) :
    i(a)
    {}
};

† 對於學究:C++ 並沒有真正的“堆棧”或“堆”/“freestore”。 我們擁有的是“自動存儲”和“動態存儲”持續時間。 在實踐中,這與堆棧分配和堆分配保持一致。

††如果你想從堆棧中“動態”分配,你需要定義一個最大大小(堆棧存儲提前知道),然后給向量一個新的分配器,以便它使用堆棧。

由於 C++11 std::array<T,size>可用於堆棧上分配的數組。 它包裝T[size]提供std::vector的接口,但大多數方法是constexpr 這里的缺點是您永遠不知道何時溢出堆棧。

std::array<myarray, 3> stack_array; // Size must be declared explicitly.VLAs

對於分配有堆內存的數組,使用std::vector<T> 除非您指定自定義分配器,否則標准實現將使用堆內存來分配數組成員。

std::vector<myarray> heap_array (3); // Size is optional.

請注意,在這兩種情況下,都需要默認構造函數來初始化數組,因此您必須定義

myarray::myarray() { ... }

也有使用 C 的VLA或 C++ 的new的選項,但您應該盡可能避免使用它們,因為它們的使用會使代碼容易出現分段錯誤和內存泄漏。

如果您創建 myarray 類的對象數組(在堆棧上或在堆上),則必須定義默認構造函數。

創建對象數組時,無法將參數傳遞給構造函數。

我知道如何使用默認構造函數創建對象,但僅在堆棧上:

假設你想用a = 1..10為 MyArray 類創建 10 個對象:

MyArray objArray[] = { MyArray[1], MyArray[2]......MyArray[10]}

無需調用析構函數,因為它們是在堆棧中創建的。

要使用以最大大小分配的堆棧內存,並通過具有運行時選擇大小的標准 stl 容器查看它,您可以使用 std::span。

#include <span>
using namespace std;

struct Toto{ int i; char name[20];};
Toto mem[100];
int n=3;
std::span<Toto> s(&mem[0], n);

我的用例涉及一個被調用一百萬次並使用幾個數組(當前為 std::vectors)的函數。 我想知道以這種方式替換 std::vector 是否會更快。 還沒有嘗試過......另一種可能性是分配std :: vector一次而不是一百萬次。

#include <stdio.h>
class A
{
public:
  A(int a){ 
       printf("\nConstructor Called : %d\n",a); 
       aM = a;
      }  
  ~A(){ 
    printf("\ndestructor Called : %d\n",aM);
}
private:
  int aM;
};

int main()
{                                                                                                   
  A **a = new A*[10];
  for (int i = 0;i<10;i++)
    a[i] = new A(i+1);
    for (int i = 0;i<10;i++)
      delete a[i];// = new A(i+1);                                                                                    

  delete []a;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM