2009-08-17 1 views
1

저는 두 개의 타사 라이브러리를 사용하고 있습니다. 둘 다 자체 2D 벡터 클래스를 구현합니다. 불행히도, 나는 그들 모두와 함께 일해야한다. 그래서 어쨌든 나는 다른 라이브러리의 함수에서 그것을 사용하려고 할 때 자동적으로 다른 것으로 변환 될 수 있도록 몇몇 "friend"함수를 작성할 수 있는가?두 개의 타사 수업을 자동으로 캐스트 하시겠습니까?

답변

1

변환 연산자는 멤버 함수 여야합니다.

이런 상황에서 필자는 convert<X,Y> 함수 템플릿을 사용하여 "캐스팅"하려는 각 쌍의 형식에 대한 완전한 전문화 또는 과부하를 사용했습니다. 이 경우 템플리트는 필요 없으며 각 방향마다 하나씩 과부하가 걸립니다. 왜냐하면 주어진 X의 경우 변환 할 수있는 것이 하나뿐이기 때문입니다.

그렇다면 하나의 매개 변수 유형을 다른 매개 변수 유형으로 변환해야하는 템플릿 코드를 사용할 때 예외적 인 경우는 거의 없습니다. 많은 소음이 들지 않고 두 API 사이의 경계를 코드에서 쉽게 볼 수 있습니다.

필자가이 상황을 많이 겪은 이유는 OS 추상화 레이어를 작성하기 때문입니다. 기본 OS에는 다양한 OS 개념에 대해 하나의 객체 세트 또는 불투명 핸들 세트가 있으며, 구현중인 API에는 다른 인터페이스가 있습니다. ConvertHostMutexToGuestMutex, ConvertGuestMutexToHostMutex, ConvertHostSocketOptsToGuestSocketOpts 등을 사용하지 않고 한 개념 집합에서 다른 개념 집합으로 "변환"하는 것이 훨씬 더 좋습니다. 단점은 일반적으로 함수가 실제로 정의 된 곳에서 광범위하게 오버로딩되는 일반적인 문제입니다.

+0

첫 번째 문장은 내가 찾던 해답이었습니다. 귀하의 솔루션은 다른 클래스를 생성하는 것보다 낫습니다. 감사 :) – mpen

2

자동 - 캐스트가 아닌 것 같습니다. 전역 변환 함수를 정의하고 명시 적으로 호출 할 수 있습니다. 해당 클래스의 정의를 게시 할 수 있습니까? 상속을 통한 트릭이 가능할 수 있습니다.

이런 식으로 뭔가하지만 자동 캐스트되지 않습니다 :

class T1 {}; 
class T2 {}; 

class UnionType : public T1, public T2 
{ 
public: 
    UnionType(const T1& val) {} // real storing should be here 
    UnionType(const T2& val) {} // real storing should be here 

    operator T1() { T1 t; return t; } // real conversion should be here 
    operator T2() { T2 t; return t; } // real conversion should be here 
}; 

int main() 
{ 
    T1 t; 
    T2 t2 = UnionType(t); 

    return 0; 
} 
+0

정말로 정의가 필요합니까? 그들은 x와 y 값을 저장합니다. http://doc.trolltech.com/4.5/qvector.html 및 http://linuxuser.at/elements/doc/box2d/structb2_vec2.htm. QVector (b2vec.x, b2vec.y)는 기본적으로 ... 하나의 구문에서 다른 것으로 변환하는 것이 어렵지 않습니다. – mpen

1

한 가지 방법은 해당 클래스에서 파생 서로에 대한 변환 연산자를 제공하는 것입니다. 하지만 코드를 통해 파생 클래스 객체를 사용해야합니다. 다음은 몇 가지 샘플 코드입니다.

class ThirdParty1 
{ 
    public: 
     ThirdParty1(int x, int y) : m_x(x), m_y(y) 
     { 
     } 
     int getX() const { return m_x; } 
     int getY() const { return m_y; } 

    private: 
     int m_x; 
     int m_y; 
}; 

class ThirdParty2 
{ 
    public: 
     ThirdParty2(int x, int y) : m_x(x), m_y(y) 
     { 
     } 
     int getX() const { return m_x; } 
     int getY() const { return m_y; } 

    private: 
     int m_x; 
     int m_y; 
}; 

template<class Type, class AdaptedType> 
class TP1Adaptor : public Type 
{ 
    public: 
     TP1Adaptor(int x, int y): Type(x,y) 
     { 
     } 
     operator AdaptedType() 
     { 
      return AdaptedType(getX(),getY()); 
     } 


}; 

typedef TP1Adaptor<ThirdParty1, ThirdParty2> First2D; 
typedef TP1Adaptor<ThirdParty2, ThirdParty1> Second2D; 

void f(ThirdParty1 tp) 
{ 
} 


void f1(ThirdParty2 tp) 
{ 
} 


int main() 
{ 
    First2D f(0,0); 
    f1(f); 


    return 0; 
} 
+0

그래 ... 나는 그것을 피하고 싶었다. 이미 가지고있는 모든 것을 다시 구현해야합니다. – mpen

+0

그럼 내가 생각할 수있는 것은 변환을하는 전역 함수입니다. – Naveen