Pokażę ci, jak rozwiązać swój problem konkretnie i jak podejść do problemów takich jak ten w ogóle.
W ogóle, podobnie jak każdy problem, że dostaje zbyt skomplikowane, spróbuj rozbicie go. Narzędzie do podziału złożonych deklaracji typów w C i C++ od dawna było "typedef". Oto, w jaki sposób podejść do niej w przypadku definicji typu kaskadowego, takich jak ta, którą posiadasz: wybierz najbardziej wewnętrzny typ owijania, tj. Unique_ptr zawijający twoją klasę i wprowadź typedef dla typu, który chcesz zawinąć. Następnie wykonaj to samo dla typu, który ten typ jest zawijany, aż znajdziesz się w najbardziej zewnętrznym typie.
To stycznie związane tylko pytania, ale chcę wspomnieć, bo można uruchomić w podobnej kwestii jak ta, którą mają teraz z szablonami późniejszych. Ponieważ C++ 11 można wygodniej zdefiniować aliasy dla typów zawierających parametry szablonu z klauzulą "using": http://en.cppreference.com/w/cpp/language/type_alias. Sprawdź ten link, jeśli jest to dla Ciebie interesujące w tym kontekście lub nabierze znaczenia w przyszłości!
Do konkretnego problemu. Funkcja "test_dynamic_2darray1" buduje dwuwymiarową tablicę inteligentnych wskaźników o wymiarach 10x10. Kiedy uruchomisz ten kod, powinieneś zobaczyć 100 linii wyjścia z destruktora, zaraz po tym, gdy zarządzana tablica wychodzi poza zakres.
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]);
}
Porównaj to z tym kodem, w którym nie będzie nazwany destruktory z dynamicznie alokowanych instancji klasy i nie widać wyjścia:
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];
}
Mam nadzieję, że udało nam się odpowiedzieć na to pytanie! :) Daj mi znać, jeśli chcesz, abym coś omawiał! Napisałem też powiązany wpis na blogu, który może Cię zainteresować: http://frankriesecodingblog.blogspot.com/2015/01/performance-of-dynamic-multi.html. Zamieszczam go tutaj, ponieważ pokazuje różne podejścia do wielowymiarowych tablic dynamicznych i analizuje działanie często sugerowanej metody wykorzystania wektorów wektorów.
Last but not least, pozwól mi wspomnieć korzystania z int iteracyjne nad tablic. Mam nadzieję, że nie zmieni się to w moją ulubienicę, ale widzę, że to dużo. Powinieneś prawdopodobnie używać size_t. Czemu? Na przykład na moim 64-bitowym komputerze "int" ma 32 bity, ale adresy reprezentowane przez size_t są 64-bitowe. To niewłaściwe użycie int było przyczyną wielu błędów, w szczególności w przenoszeniu 32-bitowych aplikacji na 64-bitowe komputery.Jeśli potrzebujesz podpisanego typu, dla takich zastosowań, jak przesunięcia między adresami tablicy, lepszym rozwiązaniem będzie prawdopodobnie ptrdiff_t.
A 1D 'vector>' powinien być dobrym zamiennikiem dla dwuwymiarowej tablicy inteligentnych wskaźników. –
juanchopanza
Ponadto tablice dwuwymiarowe nie są podwójnymi wskaźnikami. –
W C++ "dwuwymiarowa tablica X" jest napisana 'std :: vector>'. –