2010-06-19 1 views
0

어떤 유형의 값으로 ptr_map에 일부 클래스를 패킹합니다.임의로 캐스팅

class EventManager 
{ 
    ptr_map<string, any> mSomeMap; 
    public: 
     typedef signals2::signal<void (int someSignature)> KeyEvent; 
     EventManager() 
     { 
     mSomeMap["KeyPressed"] = new any(new KeyEvent()); 
     } 
}; 

이제 모든 신호 객체를 복원하고 싶습니다. 당신이 기억할 수로

template<typename EventType> 
EventType *get(const string &signalName) 
{ 
    try { 
     return any_cast<EventType*>(mSomeMap[signalName]); 
    } catch(bad_any_cast &e){} 
} 

는, 부스트의 신호가 그래서 포인터 만 저장하고 내 기능이 너무 포인터를 반환해야 noncopyable 있습니다 : 다음은이를위한 특별한 기능입니다.

이제 샘플 사용 :

evManager.get<EventManager::KeyEvent>("KeyPressed"); 
여기

내가 세그먼트 폴트를 얻을. 나는 얻을 함수에서 각 개체의 유형을 확인 : 잘못 무엇

typeid(EventType).name() 
→ N5boost8signals26signalIFvRN2sf5Event8KeyEventEENS0_19optional_last_valueIvEEiSt4lessIiENS_8functionIS6_EENSB_IFvRKNS0_10connectionES5_EEENS0_5mutexEEE 

mSignalAssociation[signalName].type().name() 
→ N10__cxxabiv119__pointer_type_infoE 

가? 주조와 일치하는 세그 폴트. 개체는 삽입 된 형식으로 구성되어야합니까? 왜 캐스팅하고 싶지 않은지.

+2

가면을 사용하기는하지만 문제가되지 않을 수도 있지만 잘못된 캐스트를 포착하고 무시한 다음 값을 반환하지 않는 것은 매우 잘못된 것처럼 보입니다. – Stephen

+0

@stephen 로깅과 다른 것들을 잘라 냈습니다. 이것은이 주제에서 중요하지 않습니다. – Ockonal

답변

3
ptr_map<string, any> mSomeMap; 

... 
    mSomeMap["KeyPressed"] = new any(new KeyEvent()); 

여기에 무슨 일이 일어 났는지 알고 있습니까? 먼저 포인터의 결과로 KeyEvent 객체를 동적으로 만듭니다. 그런 다음이 포인터는 동적으로 작성된 any-object로 랩핑되며이 포인터는 또한 할당에 의해 암시 적으로 다른 오브젝트에 다시 랩핑되는 포인터를 리턴합니다.

또한 임의의 개체에서 올바른 값을 추출하려면 정확한 형식을 알아야합니다. 따라서 예를 들어 Derived 포인터를 아무 객체 에나 포장하면 객체 유형을 추적하는 데 사용하는 std::type_info 객체의 측면에서 Base*Derived* 유형이 서로 다르므로 any_cast<Base*>을 통해 액세스 할 수 없습니다. boost::any은 포장 된 Derived -pointer를 Base- 포인터로 변환하는 방법을 알지 못합니다.

any-any -objects에 대한 포인터를 포함하여 많은 것을 포장하는 특별한 이유가 있습니까? ptr_map<KeyType,BaseType>과 같은 것을 사용하는 것이 합리적이지 않습니까? 당신은 포인터를 임의의 객체에 압축하여 여전히 포인트 티를 삭제해야한다는 것을 알고 있습니까? any-object는 당신을 위해 이것을하지 않을 것입니다.

+0

다른 기능 서명을지도에 저장해야합니다. 부스트 신호는 템플릿 화되고 복사 불가능합니다. 그래서 포인터를 저장하는 유일한 방법은 '모든', 맞죠? – Ockonal

+0

첫 단락을 얻었습니까? mSomeMap [ "KeyPressed"]는 포인터를 할당하는 boost :: lp 타입의 lvalue입니다. 따라서이 객체에 대한 포인터는 다른 객체에 래핑됩니다. 확실히 당신은 이것을 원하지 않습니다. 적절한 캐스트는 다음과 같이 될 것입니다. any_cast (* any_cast (mSomeMap [ "KeyPressed"])) – sellibitze

+0

@sellibitze, "할당에 의해 암시 적으로 다른 객체에 다시 래핑되는 포인터"라고 말했을 것입니다. 그러나 ptr_map은 boost :: any *를 가지고 있지 않으며 간단한 포인터 할당이 아니어야합니까? –