2012-11-25 3 views
0

이 질문에 이미 질문을했으나 지금은 몇 시간 씩 찾아 본 적이 있지만 비슷한 답변 만 찾을 수는 있지만 유감 스럽지만 별로 똑같은 문제는 아니며, 내 경우에는 그 중 어느 것도 작동하지 않습니다. 나는 초보 프로그래머이기 때문에 코드가 엉성한 디자인이나 아주 단순하고 어리석은 실수로 인해 작동하지 않을 가능성이 높습니다. 대안 디자인을 염두에두고 있지만 디자인이 문자 그대로 불가능하거나 내가 잘못 구현했는지 여부를 알고 싶습니다.매개 변수로 자식 참조를 수락하는 부모 함수

그래서 여기에 내가하려고하는 것이있다. 나는 2D 충돌 탐지 코드를 작성하고 있는데, 이는 폴리곤과 원 모두에서 작동해야한다. 다각형은 원과 다른 다각형에서 충돌을 감지 할 수 있어야하며 원은 다각형 및 다른 원에서 충돌을 감지 할 수 있어야합니다. 모든 클래스에 대해 별도의 벡터를 사용하지 않고 모든 콜리 전 가능한 오브젝트 (다각형과 원)를 "Collidables"라는 하나의 std :: vector에 넣을 수 있으면 좋을 것이라고 생각했습니다. 그래서 Circle과 Polygon의 부모가 될 가상 Shadow 클래스를 만들었고 가상 충돌 감지 기능을 보유하게되었습니다. Collidables 벡터는 Shape 포인터의 시퀀스가됩니다. 여기 이러한 클래스가 어떻게 생겼는지 :

//in shape.h: 
#ifndef __SHAPE_H_INCLUDED__ 
#define __SHAPE_H_INCLUDED__ 
class Polygon; 
class Circle; 

class Shape { 
//number of functions and variables irrelevant to the issue 
//relevant functions, note that Vector with capital 'V' is not std::vector but a class I wrote myself: 
    virtual Vector* detectCollision(const Shape& Collidable) const = 0; 
    virtual Vector* detectCollision(const Polygon& Collidable) const = 0; 
    virtual Vector* detectCollision(const Circle& Collidable) const = 0; 
}; 
#endif 


//in polygon.h 
#ifndef __POLYGON_H_INCLUDED__ 
#define __POLYGON_H_INCLUDED__ 
#include "shape.h" 
//edit: deleted #include "circle.h", this is now included in polygon.cpp 
//edit: deleted redundant Circle forward declaration 

class Polygon: public Shape { 
    //irrelevant stuff 
    Vector* detectCollision(const Shape& Collidable) const {return Collidable.detectCollision(*this)}; 
    Vector* detectCollision(const Polygon& Collidable) const; 
    Vector* detectCollision(const Circle& Collidable) const; 
}; 
#endif 


//in circle.h 
#ifndef __CIRCLE_H_INCLUDED__ 
#define __CIRCLE_H_INCLUDED__ 
#include "shape.h" 
//edit: deleted #include "polygon.h", this is now included in circle.cpp 
class Circle: public Shape { 
    //irrelevant stuff 
    Vector* detectCollision (const Shape& Collidable) const {return Collidable.detectCollision(*this);} 
    Vector* detectCollision (const Polygon& Collidable) const; 
    Vector* detectCollision (const Circle& Collidable) const; 
}; 
#endif 

여기 아이디어는 어떤 모양도가시 다각형 또는 원에 충돌을 감지하든 의식하지 않고 다른 모양에 충돌을 감지 할 수 있어야한다는 것입니다 detectCollision 함수를 호출합니다. 여러분이 원이고 Collidables std :: vector를 반복한다고 상상해보십시오. 첫 번째 요소는 다각형입니다. 그러나 여러분은 알지 못합니다. 여러분은 여러분이 원임을 알고 있으며, 여러분의 detectCollision 함수가 얻는 매개 변수는 Shape에 대한 참조입니다. 그래서 당신은 Shape에게 "보라, 나는 네가 무엇인지 알지 못한다.하지만 나는 원이다. 여기서 나는 스스로를 detectCollision 함수의 매개 변수로 넘기므로 그 결과를 나에게 돌려 줄 수있다." 따라서 Shape는 virtual detectCollision (const & Circle)을 호출 한 다음 실제로 작동하는 구현이 있고 그 다음 포인터 인 point를 반환해야하는 자식 인 Polygon의 detectCollision (const & Circle)에 전달됩니다. intersection (교차가없는 경우 null 포인터).

Shape 및 Polygon 클래스 만 작성된 경우이 작업은 정상적으로 작동하지만 Circle 클래스를 추가하면 코드가 더 이상 컴파일되지 않습니다. 내가 갖는 오류 : 1 : 0 : polygon.h : 멤버 함수에서 '가상 벡터 * 다각형 :: detectCollision (const를 원 &) const를' 다각형 파일에서

이 polygon.cpp에서 포함 .h : 45 : 78 : 오류 : 불완전 유형의 'const struct Circle'사용이 잘못되었습니다. shape.h : 8 : 7 : 오류 : 'const struct Circle'의 전달 선언

이 디자인을 가정합니다. 일부 가상 함수가 자식을 매개 변수로 받아들이 기 때문에 다각형은 Shape (상속하기 때문에)와 Circle (detectCollision 함수가 있기 때문에 자식을 매개 변수로 받아들이 기 때문에 모양이 자식에 달려 있습니다. Circle & 매개 변수를 허용) 및 Circle은 Shape (상속이기 때문에) 및 Polygon (polygon & 매개 변수를 받아들이는 detectCollision 함수가 있으므로)에 따라 달라집니다. 가장 쉬운 방법은 Polygons와 Circles을 하나의 시퀀스 컨테이너에 넣고 두 개의 별도 std :: vectors에 배치하는 아이디어를 포기하는 것입니다. 여전히, 내 첫 디자인이 본질적으로 불가능하고, 가능하지만 추악하거나, 단단하지만 잘못 구현되었는지 여부를 알고 싶습니다. 나는 보통 이런 종류의 물건을 혼자서 찾는 것을 선호하지만 수 시간 동안 다른 해결책을 찾고 여러 가지 시도를 한 후에이 문제를 이해하지 못한다는 것을 인정해야합니다.

(편집 : 데이브가 제안한 몇 가지 코드 변경) 사람이 더 많은 정보를 원하는 것인지

편집, 전체 소스 링크 : https://github.com/KoenP/medieval-melee-combat-cpp

난 단지 파일의 polygon.cpp을 컴파일하고를 circle.cpp , vector.cpp 및 line.cpp; test.cpp는 현재 부적합합니다. 그 벡터와 라인은이 오류에 대해 그다지 중요하지 않으며, 컴파일하지 않고 (단지 다각형과 원을 컴파일하는 것) 정확히 같은 오류를줍니다. 정확한 명령은 "g ++ -o test circle.cpp polygon.cpp line.cpp vector.cpp"입니다.

답변

1

이런 종류의 디자인은 다소 일반적입니다. 작동하게하는 방법은 헤더에 선언을 전달하는 것입니다 (#include은 아님). cpps에는 #include으로 선언하십시오. 당신은 circle.h에 ... 바른 길에

이었고 polygon.hshape.h을 포함한다. class Circle;polygon.h에서 삭제하십시오 (이미 Shape.h이 (가) 포함되어 있으므로 중복됩니다). 그런 다음 polygon.cpp에서 #include "circle.h". 그리고 circle.cpp#include "polygon.h".

+0

나를 도와 주셔서 감사합니다! 나는 아직도 작동하도록 할 수는 없지만 ... 지금 당장하고있는 일입니다. "polygon.cpp"와 "circle.cpp"파일을 컴파일 중입니다. (g ++ -o polygon.cpp circle.cpp를 테스트하십시오. "polygon.cpp"에는 "polygon.h"와 "circle.h"가 포함됩니다. "circle.cpp"는 동일한 작업을 수행합니다 (반대 순서로, 중요한지 확실하지 않음). "polygon.h"에는 "shape.h"(그리고 , 및 내 자신의 클래스 중 일부와 같은 다른 파일들이 포함됩니다). "circle.h"에는 "shape.h"도 포함됩니다. "shape.h"는 Circle과 Polygon을 선언합니다. 내가 지금 받고있는 오류는 – KoenP

+0

파일에서 포함 된 polygon.cpp : 1 : 0 : polygon.h : 'virtual Vector * Polygon :: detectCollision (const Circle &) const'의 멤버 함수에서 : polygon.h : 45 : 78 : error : 불완전한 타입 'const struct Circle'의 사용이 잘못되었습니다. shape.h : 8 : 7 : 오류 : 'const struct Circle'의 전달 선언 – KoenP

+0

@KoenP 왜 const struct circle '? 'circle'은'struct'가 아닌'클래스'입니다. 키워드를 어딘가에 혼합하고 있습니까? 'circle.h' ('polygon.cpp'에서와 같이)가 포함 된 문맥에서는 Circle이 불완전하지 않아야합니다. – David

관련 문제