c++ 소스 작성 중 다형성 관련 에러 질문입니다.

fopenfclose의 이미지

미니 게임을 만들고 있는데

말로 설명하는 것보단 .. 굉장히 간단한 게임입니다.

링크:https://youtu.be/AEFQT2Z7t_M

구현하기 위해서 나름 클래스들을 설계해봤습니다.(첨부 파일 참조)

카드 클래스를 상속 받아서

O 타입의 카드 클래스와 X 타입의 카드 클래스를 만들었습니다.

메인 함수에서는 카드에 들어갈 정보에 대한 초기화와 이 초기화된 정보로 25장의 카드를 초기화 합니다.

제가 지금까지 구현한 것은 플레이어 클래스에서 카드를 섞고 섞인 카드를 콘솔에 출력하는 부분입니다.

그런데 카드를 세팅하는 부분에서(나름 다형성을 적용했는데) 런타임 에러가 납니다.

//
void CCardGameManager::setCard(CCard ** a_pCard, Card * a_pCardMember)
{
	int i;
	for (i = 0; i < CARDCOUNT; i++)
	{
		if (a_pCardMember[i].cardType == O)
		{
			a_pCard[i] = new COCard();
			(*a_pCard)[i].setCard(a_pCardMember[i]); <-------------------- 이 부분 입니다.
		}
		else
		{
			a_pCard[i] = new CXCard();
			(*a_pCard)[i].setCard(a_pCardMember[i]);
		}
	}
}

메인 함수는 
 
<code>
 
int main(int argc, char * argv[])
{
	// 구조체
	Card oCardMember[CARDCOUNT];
	Card xCardMember[CARDCOUNT];
 
	// 카드 매니저 클래스
	CCardGameManager gameManager;
	CCard * oCard[CARDCOUNT];
	CCard * xCard[CARDCOUNT];
 
	// o 카드 세팅
	gameManager.setOcardMemberInit(oCardMember);
	gameManager.setCard(oCard, oCardMember);
 
	// x 카드 세팅
	gameManager.setXcardMemberInit(xCardMember);
	gameManager.setCard(xCard, xCardMember);
 
	CPlayer playerOne(oCard);
	playerOne.cardShuffle();
	playerOne.cardShufflePrint();
 
}

이렇게 되어 있습니다. 메모리 상의 문제인것 같은데
무슨 원인인지 잘 모르겠습니다. 가르쳐주시면 정말 감사하겠습니다. ㅜ
소스와 클래스 다이어그램은 만약을 위해서 첨부해 놓겠습니다.

File attachments: 
첨부파일 크기
Package icon TicTacToeProj.zip4.33 KB
Image icon 2.JPG44.3 KB
shint의 이미지

참고해보세요.

- rand() % 0 을 하게 되면. 오류가 발생합니다.
- char * [숫자]; 를 사용해야. 함수외부에서도 값이 그대로 적용됩니다.
- 변수[범위를 넘는 숫자] = 값; 일 경우. 오류가 발생합니다.
- 변수 초기화를 해주는것이 좋습니다.

- 할당과 해제시 주의해야 합니다.
- 비슷한 문자열은 다른 문자를 사용하시기 바랍니다.

- 함수에 인자값. 리턴값. 오류값을 확인해야 합니다. MSDN 포함.

- NULL 값 처리
- printf() 에 데이터형도 주의하시기 바랍니다.

댓글 첨부 파일: 

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

balgarac1의 이미지

가르쳐주신대로 해보겠습니다.

너무 감사합니다. ㅜ

fopenfclose의 이미지

작성해주신 소스 중에서
(a_pCard)[i] = new COCard[1] <- 이렇게 객체 배열 생성으로 되어있는데 그냥 new COCard() 하는거랑 차이가 있나요??

shint의 이미지

@.@ 복잡하네요.

new 연산자 초기화 방법 () []
new 생성자

'new operator' 와 'operator new' Programming
http://blog.naver.com/cppis?Redirect=Log&logNo=60036113050

C++ new 연산자의 진실 | ETC
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNO=20&no=8364

자바, () 와 new 의 차이점
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040201&docId=231609869&qb=bmV3ICgpIFtdIOywqOydtA==&enc=utf8&section=kin&rank=5&search_sort=0&spq=1

new 연산자와 operator new 차이 C++
http://blog.naver.com/cdh8888?Redirect=Log&logNo=220352287127

new 연산자 (C++)
https://msdn.microsoft.com/ko-KR/library/windows/apps/kewsb8ba(v=vs.120).aspx?f=255&MSPPError=-2147217396

[C++] operator new 와 메모리 지정 new(placement new) about 프로그래밍
http://blog.naver.com/mcblagg?Redirect=Log&logNo=10027082656

Placement new( new 연산자 사용시 메모리 지정 하기!! )
http://blog.naver.com/yooncj66?Redirect=Log&logNo=130161721004

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

balgarac1의 이미지

아 감사합니다. shint 님!!!

shint의 이미지


_msize() 는 윈도우에서만 가능하며.
malloc() 으로 메모리를 할당한 경우. 값을 확인하기 좋다.

_msize() 로 클래스를 메모리에 할당하면. 생성자. 소멸자만 있는 경우. 1바이트가 나온다.
멤버 변수가 있으면. 그 크기 만큼 출력 된다.

#include <iostream>
#include <stdlib.h>
 
 
class CTest
{
public:
    CTest()
    {
        printf("생성자\n");
    }
    ~CTest()
    {
        printf("소멸자\n");
        printf("\n");
    }
};
 
 
int main(int argc, char** argv) 
{
    {
        printf("CTest ct;                 \n");
        CTest ct;
    }
 
    {
        printf("CTest *p = new CTest();   \n");
        printf("delete [] p;              \n");
        printf("생성자 호출후. 소멸자 무한 반복. 소멸자를 virtual 하면 오류. \n");
    #if 0
        CTest *p = new CTest();
        delete [] p;
    #endif
        printf("\n");
    }
 
    {
        printf("CTest *p = new CTest();   \n");
        printf("delete p;                 \n");
        CTest *p = new CTest();
        printf("_msize [ %d]\n", _msize(p));
        delete p;
    }
 
    {
        printf("CTest *p = new CTest;     \n");
        printf("delete p;                 \n");
        CTest *p = new CTest;
        printf("_msize [ %d]\n", _msize(p));
        delete p;
    }
 
    {
        printf("CTest *p = new CTest;     \n");
        printf("delete [] p;              \n");
        printf("생성자 호출후. 소멸자 무한 반복. 소멸자를 virtual 하면 오류. \n");
    #if 0
        CTest *p = new CTest;
        delete [] p;
    #endif
        printf("\n");
    }
 
    {
        printf("CTest *p = new CTest[0];  \n");
        printf("delete [] p;              \n");
        printf("생성자와 소멸자가 호출이 안됨. \n");
    #if 1
        CTest *p = new CTest[0];
        printf("_msize [ %d]\n", _msize(p));
        delete [] p;
    #endif
        printf("\n");
    }
 
    {
        printf("CTest *p = new CTest[1];  \n");
        printf("delete [] p;              \n");
    #if 1
        CTest *p = new CTest[1];
        printf("_msize [ %d]\n", _msize(p));
        delete [] p;
    #endif
        printf("\n");
    }
 
	return 0;
}
 
 
 
 
출력 결과.
 
 
CTest ct;
생성자
소멸자
 
CTest *p = new CTest();
delete [] p;
생성자 호출후. 소멸자 무한 반복. 소멸자를 virtual 하면 오류.
 
CTest *p = new CTest();
delete p;
생성자
_msize [1]
소멸자
 
CTest *p = new CTest;
delete p;
생성자
_msize [1]
소멸자
 
CTest *p = new CTest;
delete [] p;
생성자 호출후. 소멸자 무한 반복. 소멸자를 virtual 하면 오류.
 
CTest *p = new CTest[0];
delete [] p;
생성자와 소멸자가 호출이 안됨.
_msize [-1]
 
CTest *p = new CTest[1];
delete [] p;
생성자
_msize [-1]
소멸자

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

twinwings의 이미지

(*a_pCard)[i].setCard(a_pCardMember[i]);

가 아니라

*(a_pCard[i]).setCard(a_pCardMember[i]);

가 아닌가요. a_pCard 변수의 타입이 CCard ** 인데..(타입은 맞지만 잘못된 위치에서 객체로서 참조하고 있습니다.)

twinwings의 이미지

좀 더 보기좋게 적으면

void CCardGameManager::setCard(CCard ** a_pCard, Card * a_pCardMember)
{
	int 	i;
	CCard*  p_card = NULL;
	for (i = 0; i < CARDCOUNT; i++)
	{
		if (a_pCardMember[i].cardType == O)
		{
			p_card = new COCard();
		}
		else
		{
			p_card = new CXCard();
		}
 
		// 다형성을 가지고 있으므로 이렇게 처리하는게 더 좋습니다.
		a_pCard[i] = p_card;
		p_card->setCard(a_pCardMember[i]);
	}
}

그리고 객체지향으로 코딩하시려면, 객체에 대한 Pool도 같이 typedef로 정의하는게 좋습니다.
low level인 배열등은 쓰지 않는게 좋습니다.

class CCard {...}
typedef std::map<int, CCard*> CCardPool;
typedef std::vector<CCard*> CCardPool;
typedef std::vector<CCard> CCardPool;

이런 식으로 말이죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.