2011-12-28 8 views
-1

등급과 정장을 나타내는 2 개의 정수를 저장하는 클래스 카드가 있습니다. 그리고 배열에 저장된 52 개의 Card 객체를 포함하는 클래스 Deck을 가지고 있습니다. 갑판을 초기화하면 52 장의 카드를 모두 만들고 갑판에 추가합니다.이 상황에서 새로운 기능을 사용해야합니까?

나는 이것이 내가

deck[i] = Card (rank, suit); 

또는

deck[i] = new Card (rank, suit); 

이유는 하나 또는 다른을 사용할 것

사용해야 할 때? 하나가 유효 deck[i] = new Card (rank, suit);

+11

메모리 관리 각 Card 대해 별도의 메모리 블록을 할당하지 않고, 그리고 기본적으로 구조가 필요하고 별도, 예 Card 값을 복사하여 할당없이 생성자 C++에서는 복잡한 문제입니다. 사람들은 그것에 관한 책을 씁니다. 읽어야합니다. –

답변

5

는 첫 번째 원하는, Card의 배열입니다 .

배열 객체가 포함 된 경우

,

deck[i] = Card (rank, suit); 

유효합니다.

배열 객체에 대한 포인터가 포함되어있는 경우

,

deck[i] = new Card (rank, suit); 

유효합니다.

컴파일하려고하면 그 중 하나에 오류가 발생하는 것입니다. 다른 하나는 당신이 원하는 것입니다.

+0

그리고 후자의 경우에, 당신은 _ 매우 ~ 싶습니다. –

3

때문에, 하나는되지 않습니다 : Card*의 배열 인 deck[i] = Card (rank, suit);

deck 경우, 두 번째를 원하는 : deck 만약

2

이 경우 Card 배열 또는 Card* 배열을 사용하면 장단점이 있습니다. 포인터 배열의 경우 메모리 누출을 방지하기 위해 배열을 삭제하기 전에 모든 포인터를 수동으로 삭제해야합니다. 이것은 또한 메모리에서 아주 작은 공간을 더 많이 차지합니다. 장점으로, 예를 들어 포인터 만 바꾸면 두 카드를 쉽게 교체 할 수 있습니다. 개체가있는 경우이를 바꾸려면 개체를 수정하거나 새로운 개체를 구성해야합니다 (값 비쌀 수 있음). 덱은 당신이 포인터를 선택한 경우에도 카드를 공유 할 수 있습니다 (나는이 특별한 경우에 왜이 카드를 사용하는지 모르지만 일반성을 위해 알고있는 것이 유용합니다).

개체 배열이있는 경우 메모리 관리에 대해 걱정할 필요는 없지만이 빠른 스와핑 기능을 잃게됩니다.

어느 것이 응용 프로그램에 더 좋을지 평가하는 것은 당신에게 달려 있지만, 나는 개인적으로 당신이 객체의 배열로 괜찮을 것이라고 생각합니다.

+0

나는 문자 그대로의 질문에 대답했다. 그러나 이것은 질문자가 찾고있는 것 같다. –

3

각 사례에 대해 deck 배열을 적절하게 선언했다면 제안하는 두 옵션이 모두 유효합니다. 나 각 옵션의 장점을 논의하자 모든 할당을 암시하고 컴파일러에 의해 관리되기 때문에

deck[i] = Card (rank, suit);

  • 필요, 메모리를 관리 할 수 ​​있습니다. 포인터로 작업하는 것은 좀 더 많은 노력이 필요합니다.
  • Card 클래스가 간단하다고 가정하면 컴파일러에서 생성 된 기본 복사 및 할당 논리로 충분하므로 Card 인스턴스를 할당하거나 인수로 전달하는 것과 같은 기본 유형 인 것처럼 사용할 수 있습니다.
  • 참조를 신중하게 사용하면 인스턴스 복사를 줄이고 해당 인스턴스와 관련된 성능 저하를 최소화 할 수 있습니다.

deck[i] = new Card (rank, suit);

  • 각 카드 게임의 수명을 통해 고유
  • . 중복되지 않는 독특한 카드로 게임을 모델링하는 것이 더 쉽습니다.
  • 보다 효율적입니다. 인수로 카드를 건네 주면 각 배열이 얼마나 큰 지 상관없이 포인터가 전달됩니다. 다른 배열간에 카드를 이동하는 것과 같습니다. 다른 경우와 비교할 때 Card 인스턴스를 값으로 이동하려면 클래스의 전체 내용을 메모리의 한 위치에서 다른 위치로 복사해야합니다.
  • 카드가 고유하고 결코 복사되지 않으면 게임 상태를 디버그하는 것이 더 쉬울 수 있습니다.

내 생각에 두 가지 방법 모두 명확한 이점은 없지만 Card 클래스가 너무 작 으면 더욱 그렇습니다. 나는 아마도 포인터로 직접 갈 것이지만, 객체의 사용은 나쁜 선택이 아니다.

행운을 빈다. 당신이 Card 항목의 배열을 선언하면

1

은 다음 항목이 기본적으로 구성 배열 할당하면 될 것입니다, 그리고 당신은 예를 들어, 돌아가서 이후에 새로운 값으로 개별 Card 항목을 업데이트 할 수 있습니다

Card deck[52]; 
for (int i = 0; i < 52; ++i) 
{ 
    rank = ...; 
    suit = ...; 
    deck[i] = Card(rank, suit); 

    // better, add a method to the `Card` class to 
    // update the values without constructing any 
    // temporary instances at all... 
    // 
    // deck[i].set(rank, suit); 
} 

당신이 Card 포인터의 배열을 선언하는 경우에, 당신이 원하는 값으로 각 Card 항목을 초기화하기 위해 Card 생성자를 사용하지만 각 Card 항목에 대한 별도의 메모리 블록을 할당하는 비용, 예에서 할 수 있습니다

Card* deck[52]; 
for (int i = 0; i < 52; ++i) 
{ 
    rank = ...; 
    suit = ...; 
    deck[i] = new Card(rank, suit); 
} 

당신이 배열 대신 std::vector를 사용하는 경우는 예를 들어, 두 가지를 결합 할 수 있습니다 : 당신이 placement new 연산자를 사용하는 경우 Card 전화를

std::vector<Card> deck(52); 
for (int i = 0; i < 52; ++i) 
{ 
    rank = ...; 
    suit = ...; 
    deck[i] = Card(rank, suit); 

    // or: 
    // deck[i].set(rank, suit); 
} 

는, 당신은 실제로 '새'연산자를 이용할 수있다

unsigned char deck_buffer[sizeof(Card) * 52]; 
Card *deck = (Card*) deck_buffer; 
for (int i = 0; i < 52; ++i) 
{ 
    rank = ...; 
    suit = ...; 
    new (&deck[i]) Card(rank, suit); 
} 
관련 문제