2016-08-16 3 views
1

내가 시험을 위해 공부하고 시험 시험 그들이 포인터 - 투 - 포인터 객체를 사용하여 동적를 만들기의 요구 사항을 넣어ptr-to-ptr 배열 사용? 이 같은의 사용과 설명은 무엇

int capacity; 
int** number; 
this->number = new int*[this->capacity]; 

? : 그것으로부터 배열. 두 가지 클래스가 있습니다. 월렛 & 월렛 키퍼.

private: 
    Wallet** wallets; 
    int capacity; 
    int size; 
    /*other stuff below this*/ 

그리고 생성자 : 그들은 WalletKeeper의 헤더 파일에 이런 짓을 솔루션에

Wallet * wallets = new Wallet[capacity]; 

:

WalletKeeper::WalletKeeper(int capacity) 
{ 
    this->capacity = capacity; 
    this->size = 0; 
    this->wallets = new Wallet*[this->capacity]; 
    this->initiate(); 
} 

는이 같은 기본 동적 배열을 이해 즉,이 월렛 배열이있는 메모리의 위치를 ​​가리키는 포인터를 만들면 해당 메모리 슬롯의 내용을 변경할 수 있습니다. 하지만 포인터 배열에 대한 포인터를 만드는 이유는 무엇입니까? 그게 무슨 용도예요? 나는이 글을 읽을 때문에

지갑 자체의 어떤 배열이 없다, 나는 그렇지 않으면 이해 한 것 : The correct way to initialize a dynamic pointer to a multidimensional array?

교수는 속히까지 휴가에 있습니다.

+0

왜 당신은 이제까지 다른 배열을 포함 할 수 있습니다 배열의 배열을 만들 것? 예를 들어, 행렬은 배열의 배열로 표현 될 수 있습니다 (각 행에 대한 숫자의 배열, 전체 행렬은 단지 행의 배열입니다). – ForceBru

+6

나는 대답하기 위해 노력하고 있습니다.하지만 그 전에는 교수님이 아직도 이런 식으로 C++을 가르치는 것이 얼마나 소름 끼치는가를 표현하고 싶습니다. 그들은 단지'std :: vector '또는'std :: vector > '객체를 사용하도록 가르쳐 줬어야했는데,이 객체는 오류가 발생하기 쉽고 적합하지 않은 객체보다 무한히 바람직합니다. 실용적인 애플리케이션 코드. – Xirema

+1

Wallet * 배열입니다. 이것은 "자연스러운"현대 C++가 아니며 컨테이너 클래스를 사용하여 수행해야하며 일반적으로 메모리의 원시 할당은 가능하면 피해야합니다. – crashmstr

답변

1

기본적인 개념은 "배열 배열"을 만들 수 있다는 것입니다. 매트릭스에 비해 좁은 서브 어레이를 가질 수 있다는 장점이 있지만 모든 오브젝트의 메모리가 전체 어레이에서 더 이상 연속적이지 않다는 단점이 있습니다. 그 코드에 w_ptr_ptr[0]w_ptr_ptr[1]보다 상이한 크기의 배열을 가지고있는 것을

Wallet ** w_ptr_ptr = new Wallet*[capacity]; 
for(int i = 0; i < capacity; i++) { 
    w_ptr_ptr[i] = new Wallet[i+1]; 
} 

for(int i = 0; i < capacity; i++) { 
    for(int j = 0; j < i+1; j++) { 
     w_ptr_ptr[i][j] = Wallet(/*...*/); 
    } 
} 

참고.

내 의견에 언급했듯이 교수님이 이렇게 가르쳐서는 안됩니다. 이 코드는 수동으로 메모리 정리가 필요하며, 자동 경계 검사를 할 수있는 능력을 가지고 있지 않기 때문에, 사용되어야하는 코드는 다음과 같습니다

std::vector<std::vector<Wallet>> wallets; 

for(int i = 0; i < capacity; i++) { 
    wallets.emplace_back(i+1); //Will automatically create a i+1-sized array. 
} 

for(int i = 0; i < wallets.size(); i++) { //Note I'm able to query the size here! 
    for(int j = 0; j < wallets[i].size(); j++) { //Again I can query the size! 
     wallets[i][j] = Wallet(/*...*/); 
    } 
} 
+0

더 많은 코드를 보지 않고도, 'Wallet'의 배열 배열이나'Wallet * '배열 인 것으로 가정 할 수 없습니다. 나에게'월렛 키퍼 (Wallet Keeper) '가'월렛 * (Wallet *)'을 갖고 자하는 것이 더 합리적이다. – crashmstr

+0

@crashmstr 글쎄요, 포인터 배열 (Wallet *)을 가리키는 ptr2ptr (월렛 **) 만 있고, 아무데도 가리 키지 않는 경우입니다. 그래서 내가 혼란 스럽기 때문에, 각각 모두 배열을 가리키고 있다면 이해할 수있을 것입니다. –

+0

그러면 코드는 나중 단계로 포인터에 '새 월렛'을 할당하거나 할당합니다. 이렇게하는 이유는 '월렛'개체를 앞에 할당하지 않기 때문입니다. 안전하게하기 위해서 배열을'nullptr'로 초기화 할 필요가 있습니다 (그리고 슬롯이 점유되어 있는지 검사 할 수 있습니다). – crashmstr

3

포인터 배열은 여러 용도로 사용됩니다.

  1. 재정렬. 배열의 객체 순서를 변경하려고한다고 가정합니다. 포인터를 다루는 것은 전체 객체를 움직이는 것보다 훨씬 빠릅니다.
  2. 동적 할당. 각 개체를 개별적으로 삭제하거나 할당 할 수 있습니다.
  3. 재 할당 및 성능. 배열의 크기를 늘리고 싶다고 가정 해보십시오. 실제 개체를 재 할당하면 다른 유형의 문제 (무효화)가 발생할 수 있습니다. 그러나 포인터의 배열을 재 할당하면 다소 문제가 발생하지 않으며 훨씬 빠릅니다.
+0

포인터 배열을 사용하면 배열의 여러 요소가 동일해야한다면 포인터를 다시 사용하여 많은 메모리를 절약 할 수 있습니다. –

0

포인터 - 객체에 대한 포인터가 행렬 구현에 사용 된 일반적입니다 .

Wallet* wallets = new Wallet[capacity]; 

은 납입 용량 Wallet 객체에 배열의 첫 번째 위치를 가리 킵니다 지갑을한다 : 당신은 당신의 질문에서 제시 한 바와 같이 실제로 객체에 대한 포인터 등이 동적 배열을 구현합니다. 추천 포인터

[Wallet-obj] [Wallet-obj] [Wallet-obj] ... [Wallet-obj] 
    0   1    2   capacity - 1 

포인터 :

[Wallet-pointer] [Wallet-pointer] [Wallet-pointer] ... [Wallet-pointer] 
     0    1     2    capacity-1 

는 벡터의 각 포인터가 동적 배열을 가리켜 야 :

Wallet** wallets = new Wallet*[capacity]; 

월렛 포인터 배열을 만든다.

나는 표현을 "그리는"하려고합니다 :

[0][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj] 
[1][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj] 
... 
[capacity-1][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj] 

그래서 당신은 같은 것을 사용해야 개체에 액세스하려면 : 1-일에 액세스 의미

wallets[0][2]; 

을 포인터의 배열에있는 포인터, 해당 행의 3 번째 개체에 대한 개체 액세스의 1 "행"을 사용합니다.

이미지를 만들면 n 개의 용량 행과 같은 n 개의 용량 동적 배열이 있기 때문에 매트릭스가 있습니다.

당신은 포인터의 배열을 인스턴스화 주

, 당신은 그들 각각을 초기화해야합니다. 이 완전한 코드 :

Wallet** wallets = new Wallet*[capacity]; 

// Now for each pointer you have to allocate a dynamic array of n-elements. 
for (size_t i = 0; i < capacity; ++i) { 
    wallets[i] = new Wallet[capacity]; 
} 

그리고 같은이 해제 단계입니다 :

// First of all, deallocate each object in each dynamic array: 
for (size_t i = 0; i < capacity; ++i) { 
    delete[] wallets[i]; // wallets[i] is a dynamic array to deallocate 
} 

// Finally deallocate the dynamic array of poiter 
delete[] wallets;