저는 Connect 4 게임을 디자인하고 있습니다. 지금까지 기본 클래스가 4 개 있습니다 :`this '가 0x0와 같은 이유로 내 프로그램이 중단되는 이유는 무엇입니까?
Colour
- 색상 표현 (RGBA)을 담당합니다. 변환 연산자가 포함되어 있습니다.
Player
- 게임의 플레이어를 나타냅니다. 각 Player
에는 Colour
과 이름이 있습니다.
Board
- 재생 보드를 나타냅니다. 여기에는 치수뿐만 아니라 해당 치수의 Tile
2 차원 벡터가 포함됩니다.
Tile
- 중첩 된 클래스는 Board
입니다. 보드의 한 칸을 나타냅니다. 각 Tile
은 Colour
이고 해당 타일의 소유자는 std::unique_ptr
입니다. 소유자는 nullptr
으로 시작하며 번에서 Player
으로 한 번 변경할 수 있습니다. 색상은 투명한 검은 색으로 시작됩니다.
내 Colour
클래스를 테스트했는데 정상적으로 작동하는 것 같습니다. 내 Player
클래스도 tip-top 모양입니다. 그러나 Board/Tile
클래스에 문제가 있습니다.
내 테스트는 두 명의 플레이어와 보드를 만드는 것으로 구성되었습니다. 이들은 정상적으로 실행됩니다. 다음으로, 각 타일에 대해 보드의 치수를 반복합니다. 그때 j
, 당신이 그것을 인쇄 기대하는 방식으로 i
와 행과 열을 통해
board.tile (j, i).claimBy (p2);
루프가 간다를 호출합니다.
tile (j, i)
은 내가 작업중인 타일을 가져옵니다. 그것은 예상대로 작동합니다. 크래시에 주요 이벤트의
체인 :
claimBy (p2)
는 타일을 설정은 다음과 같이 구현되어 플레이어 (2)에 의해 주장 될 수 있습니다 :
bool Board::Tile::claimBy (const Player &owner)
{
if (!_owner)
{
*_owner = owner;
_colour = owner.colour();
return true;
}
return false;
}
_owner
내 std::unique_ptr<Player>
입니다. 타일의 소유자가 이전에 설정되었는지 (즉, nullptr
이 아닌지) 먼저 확인합니다. 그렇지 않으면 전달 된 값으로 내부에 Player
을 설정 한 다음 타일의 색상을 업데이트하고 true
을 반환합니다. 이전에 소유권을 주장한 타일은 false
을 반환합니다.
디버거가 끝나면 *_owner = owner;
줄에서 충돌이 발생합니다. 스텝을 밟으면 struct Player
(내 선언은 Player
클래스)입니다. 암시 적 복사 생성자가됩니다 (클래스는 Colour _colour
및 std::string _name
만 기억하십시오).
스테핑을 다시 수행하면 Colour::operator=
이됩니다 (복사 생성자가 호출하는 것이 좋습니다).정의는 다음과 같습니다.
Colour &Colour::operator= (const Colour &rhs)
{
if (*this != rhs)
{
_red = rhs.red();
_green = rhs.green();
_blue = rhs.blue();
_alpha = rhs.alpha();
}
return *this;
}
경로는 *this != rhs
으로 바뀝니다.
return red() == rhs.red()
&& green() == rhs.green()
&& blue() == rhs.blue()
&& alpha() == rhs.alpha();
여기 red() == rhs.red()
첫 번째 비교 그냥 return _red;
입니다 red()
이있는이 단지입니다 operator==
에 역 호출이다. 이것은 프로그램이 충돌하는 지점입니다. 디버거에 this
(this->_red
)이 0x0이라고 나와 있습니다.
왜 이런 일이 일어나고 있는지 알 수 없습니다. 내 생각 엔 스마트 포인터를 잘못 사용하고있는 것 같습니다. 전에는 실제로 사용하지 않았지만 정상적인 포인터와 매우 유사해야하며 포인터가 nullptr
인 경우 release
은 아무 것도 수행하지 않을 것이라고 생각했습니다.
this
이 0x0 일 수 있습니다.
편집 :
나는 각각의 생성자에서 그렇게으로 확인 모든 NONE 투명 블랙 없다 멤버 이니셜 라이저 (예를 들어 Board::Tile::Tile() : _colour (Colours::NONE), _owner (nullptr){}
)에, 초기화입니다.
나는 디버깅 값을 인쇄하는 데 그다지 사용하지 않았기 때문에 디버거도 능숙하지 못합니다.
사이드 노트 : 타일이 보드가되는 것이 맞습니까? – Cameron
@Cameron, is-a 관계는 상속과 관련이 있습니다. 'Tile' 클래스의 나의 목표는'Board'에 완전히 포함시키는 것이 었습니다. 'tile' 함수는 원래'const' 리턴 이었지만, 방금 테스트를 위해 변경했습니다. 타일은 'Board'외부에서 액세스 할 수 있지만 작업 한 바로는 새 타일을 만들 수 없습니다. 물론 'Board'는 타일 벡터를 통해 비 const 액세스를 제공합니다 (제공하는 관계가 있습니다). 즉, 보드 객체에는 타일의 2D 벡터가 있습니다. – chris
디자인에 관련없는 의견 : 보드를 조작하는 게임 논리가 RGBA 색상에 관심을 가져서는 안됩니다. 타일을 제어하는 플레이어를 참조하고 그리기 코드가 어떤 플레이어인지에 따라 색상을 선택하게하십시오. – Wyzard