Syntax for dynamically allocating a 2D array of smart pointers


I need to dynamically allocate a two dimensional array of smart pointers but the syntax for it is confusing me. I need this to be dynamic:

我需要動態分配一個智能指針的二維數組,但它的語法讓我很困惑。我需要這個是動態的:

std::unique_ptr<someClass> myArray[size1][size2];

So from what I understand I create a pointer to a pointer to the type:

所以根據我的理解,我創建了一個指向該類型的指針:

someClass** myArray; //actaully the type is std::unique_ptr<someClass> but I'll just keep it simple

Then to allocate it I do:

然后分配它我做:

myArray* = new someClass*[size1];
for(int i = 0; i < size1; i++)
    myArray[i] = new someClass[size2];

But this doesn't use smart pointers which means I will have to manually delete it later, and I don't know how to make these pointers smart pointers;

但這不使用智能指針,這意味着我將不得不在以后手動刪除它,我不知道如何使這些指針智能指針;

The type is std::unique_ptr but then I need a pointer to a pointer to the type, so I tried:

類型是std :: unique_ptr但是我需要一個指向該類型的指針,所以我試過:

std::unique_ptr<std::unique_ptr<std::unique_ptr<someClass>>> myArray;

But after this I'm lost on how I would allocate it. Could someone please help me out?

但在此之后,我迷失了如何分配它。有人可以幫幫我嗎?

2 个解决方案

#1


3  

I'll show you how to solve your problem specifically and how to approach problems like this one in general.

我將向您展示如何具體解決您的問題以及如何解決像這樣的問題。

In general, just like any problem that gets too complex, try to break it down. The tool for breaking down complex type declarations in C and C++ has long been the "typedef". Here is how you approach it for cascaded type definitions like the one you are having: take the innermost wrapping type, i.e. the unique_ptr wrapping your class, and make a typedef for the type you want to wrap. Then, proceed doing the same for the type which that type is wrapping, until you are at the outermost type.

一般來說,就像任何過於復雜的問題一樣,嘗試將其分解。用於在C和C ++中分解復雜類型聲明的工具長期以來一直是“typedef”。下面是如何處理類似於您所擁有的級聯類型定義:采用最里面的包裝類型,即包裝類的unique_ptr,並為要包裝的類型創建一個typedef。然后,繼續對該類型包裝的類型執行相同操作,直到您處於最外層類型。

This is tangentially related to your question only, but I want to mention it, because you might run into a similar issue like the one you are having now with templates later. Since C++11 you can more conveniently also define aliases for types involving template parameters with the "using" clause: http://en.cppreference.com/w/cpp/language/type_alias. Go check out that link if that is of interest to you in this context or becomes relevant in the future!

這與您的問題僅相關,但我想提及它,因為您可能會遇到類似於您現在使用模板的類似問題。從C ++ 11開始,您可以更方便地使用“using”子句為涉及模板參數的類型定義別名:http://en.cppreference.com/w/cpp/language/type_alias。如果在這種情況下您感興趣或在將來變得相關,請查看該鏈接!

To your specific problem. The function "test_dynamic_2darray1" builds a two-dimensional 10x10 array of smart pointers. When you run this code, you should see 100 lines of the output from the destructor, just when the managed array goes out of scope.

針對您的具體問題。函數“test_dynamic_2darray1”構建了一個二維10x10智能指針數組。當您運行此代碼時,您應該看到析構函數輸出的100行,就在托管數組超出范圍時。

size_t destructor_count = 0;
class MyClass {
    public:
    ~MyClass() {
        std::cout << "Destructor call #" << ++destructor_count << std::endl;
    }
};

typedef std::unique_ptr<MyClass[]> ManagedC;

void test_dynamic_2darray1() {
    size_t dimension1 = 10, dimension2 = 10;

    auto managed_array = std::unique_ptr<ManagedC[]>(new ManagedC[dimension1]);
    for (size_t i = 0; i < dimension1; ++i)
        managed_array[i] = ManagedC(new MyClass[dimension2]);
}

Compare that to this code, where the destructors of the dynamically allocated class instances will not be called and you see no output:

將其與此代碼進行比較,其中不會調用動態分配的類實例的析構函數,並且您看不到輸出:

void test_dynamic_2darray2() {
    size_t dimension1 = 10, dimension2 = 10;

    auto simple_array = new MyClass*[dimension1];
    for (size_t i = 0; i < dimension1; ++i)
        simple_array[i] = new MyClass[dimension2];
}

I hope I have been able to answer your question! :) Let me know if you want me to elaborate on something! I also wrote a related blog post the other day that may interest you: http://frankriesecodingblog.blogspot.com/2015/01/performance-of-dynamic-multi.html. I am posting it here, because it shows different approaches to multi-dimensional dynamic arrays and looks into the performance of the often suggested method of using vectors of vectors.

我希望我能夠回答你的問題! :)如果你想讓我詳細說明,請告訴我!前幾天我還寫了一篇你可能感興趣的相關博客文章:http://frankriesecodingblog.blogspot.com/2015/01/performance-of-dynamic-multi.html。我在這里發布它,因為它顯示了多維動態數組的不同方法,並研究了使用向量矢量的常用方法的性能。

Last but not least, let me mention your use of int to iterate over arrays. I hope this isn't turning into a pet peeve of mine, but I see this being done a lot. You should probably use size_t. Why? For example, on my 64 bit machine "int" is 32 bit, but addresses, represented by size_t, are 64 bit. This misuse of int has been the cause of many bugs, in particular for porting 32 bit applications to 64 bit machines. If you need a signed type, for uses such as offsets between array addresses, a better use would probably be ptrdiff_t.

最后但同樣重要的是,讓我提一下你使用int迭代數組。我希望這不會變成我的寵兒,但我看到這已經做了很多。你應該使用size_t。為什么?例如,在我的64位機器上,“int”是32位,但是由size_t表示的地址是64位。這種對int的誤用是造成許多錯誤的原因,特別是對於將32位應用程序移植到64位機器。如果您需要簽名類型,對於諸如數組地址之間的偏移之類的用途,更好的用途可能是ptrdiff_t。

#2


2  

As an illustrative example, below is the syntax that can be used in C++ modern for creating and filling a 2D int array (of size 3 by 5) using smart pointer (unique_ptr) and other features such as make_uniqueand move().

作為一個說明性示例,下面是可以在C ++現代中使用的語法,用於使用智能指針(unique_ptr)和其他功能(如make_unique和move())創建和填充2D int數組(大小為3 x 5)。

unique_ptr<unique_ptr<int[]>[]>     smartPtr2D;
unique_ptr<int[]>                   smartPtr1D;

int dataCounter = 0;

smartPtr2D = make_unique< unique_ptr<int[]>[] >(3);
for (int i = 0; i<3; i++)
{
    smartPtr1D = make_unique<int[]>(5);
    for (int j = 0; j<5; j++)
    {
        smartPtr1D[j] = dataCounter;
        dataCounter++;
    }
    smartPtr2D[i] = move(smartPtr1D);
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com