princetonpku / hccl-archive

Automatically exported from code.google.com/p/hccl-archive
0 stars 0 forks source link

typecast시, 서로 다른 클래스간 참조 관련 #14

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
현재 Vector-Quaternion간 혹은 Quaternion-Vector간 typecast를 제가 
구현해둔 상태인데,
#ifdef ~ #endif문을 이용하여 구현하였습니다.

즉, Quaterniond --> Vector3d의 경우
#ifdef Quaterniond
Vector3d(const Quaterniond& q);
#endif
와 같은 형태로 type-cast 생성자가 구현되어 있습니다.

본래 목적은 Vector3d만 사용하는 사용자들은 굳이 
Quaternion.h를 include하지 않아도 되도록 하기 위해서였고, 
따라서 Quaternion.h가 Vector.h와 함게 #include가 되어 있는 
경우에만 저 코드가 컴파일 되도록 만든 것입니다.

헌데, 지금 가만 생각해보니 include 순서에 따라 typecast가 
한방향으로만 된다는 문제가 있네요..;;
예를들어 Quaternion.h가 Vector.h보다 먼저 선언이 되어있다면
Vector(const Quaterniond& q);
는 사용이 가능하지만
Quaternion(const Vector3d& v);
는 사용이 불가능합니다.

이 문제를 어떻게 해결해야 할 지 좀 깔끔한 대책 혹은 
트릭을 알려주시면 좋겠네요.
이건 코드에다 직접 수정하지 마시고 아래에 comment로 
남겨주시면 제가 수합해서 코드 교정하도록 하겠습니다.

(comment 다실때 status는 반드시 new로 해주세요.)

Original issue reported on code.google.com by mec...@gmail.com on 24 Jul 2012 at 9:40

GoogleCodeExporter commented 9 years ago
흠 헤더할때
ifdef~

하니까

그걸 이용해서 class 명만 선언해놓으면 되지 않을까요?

어차피 레퍼런스 참조니까.

Original comment by hounh...@gmail.com on 24 Jul 2012 at 9:43

GoogleCodeExporter commented 9 years ago
Vector.h 파일 맨 앞쪽에
class Quaternion;

Quaternion.h 파일 맨 앞쪽에
class Vector;

로 forward declaration하면 될 듯합니다

Original comment by thegoogo...@gmail.com on 24 Jul 2012 at 9:47

GoogleCodeExporter commented 9 years ago
근데 그렇게하면 구현부에서는? 그리고 forward 
declaration을하면 ifdef는 무조건 쌩까는거 아니여? 코드 
올려놨으니깐 한번 봐줘염

Original comment by mec...@gmail.com on 24 Jul 2012 at 9:55

GoogleCodeExporter commented 9 years ago
Q->V 혹은 V->Q로 casting하려면
최소한 cpp 파일에서는 상대방의 header 파일을 참조해야 
하므로 보통 방법으로는 어려워 보입니다.

사용할 때마다 *h,*cpp 파일을 프로젝트에 복사해서 쓸 때, 두 
클래스를 동시에 들고다니는 것이 번거롭기 때문으로 
보입니다.
하지만 3rd party 라이브러리 형식으로 만들고 작업하는 
프로젝트 외부에서 참조하여 사용한다면 두 클래스에 
의존성이 생기는 것에는 문제 없어보이고요.

한가지 방벙으로는 compile 시에
USE_ONLY_VECTOR, USE_ONLY_QUATERNION, USE_VECTOR_AND_QUATERNION
등과 같은 preprocessor symbol을 통해 header 파일을 참조하지 
않도록 할 수 있겠지만, 사용자 입장에서 쓰기 어려워질 것 
같습니다.

다른 의견 있으시면 남겨주세요.

Original comment by thegoogo...@gmail.com on 24 Jul 2012 at 10:59

GoogleCodeExporter commented 9 years ago
그럼 결국 VectorQuaternion.h라는 파일을 따로 하나 만드는 수 
밖에 없는건가요?
VectorQuaternion.h에서 Vector.h랑 Quaternion.h를 다 include해버리고, 
include문 앞에 USE_TYPECAST같은 거 하나 define하는 방식으로...
그럼 Vector.h나 Quaternion.h에서는
#ifdef USE_TYPECAST
Quaterniond(const Vector3d& v);
#endif
이런 식으로 쓰면 될 거고..

그렇게되면 typecast 안할 사람들은 Vector.h나 Quaternion.h 
따로따로 include해서 쓰면되는거고, typecast 필요한 사람들은 
VectorQuaternion.h를 include해서 한방에 쓰면 되니깐 일단 문제는 
해결이네요.

원래 처음에 이런 방식으로 구현하려고 했는데, 사용자 
입장에서 좀 혼란스러울 것 같기도 해서 일단 그렇게는 
안한건데... 혹시 더 좋은 의견 있으신 분들은 남겨주세요.

Original comment by mec...@gmail.com on 24 Jul 2012 at 11:11

GoogleCodeExporter commented 9 years ago
템플릿을 이용하면 소스파일 의존성은 없앨 수 있겠네요.

//Quaternion to vector
template<typename Q> Vector(const Q &a)
{
    val[0] = a.val[1];
    val[1] = a.val[2];
    val[2] = a.val[3];
}

// Vector to Quaternion
template<typename V> Quaternion(const V &a)
{
    val[0] = 0;
    val[1] = a.val[0];
    val[2] = a.val[1];
    val[3] = a.val[2];
}

val이라는 이름의 배열을 가진 객체에 대해서는 모두 적용할 
수 있는데, 이는 장점이자 단점이네요. 생각지 못한 곳에서 
위의 템플릿이 적용되는 경우가 있습니다.

Original comment by thegoogo...@gmail.com on 24 Jul 2012 at 11:56

GoogleCodeExporter commented 9 years ago
저는 Comment5 방법도 괜찮은것 같네요.

Original comment by nall...@gmail.com on 26 Jul 2012 at 6:13

GoogleCodeExporter commented 9 years ago
VectorQuaternion.h에 Vector와 Quaternion 모두 넣어버리기로 하였음

Original comment by mec...@gmail.com on 27 Jul 2012 at 2:08