2011-03-03 2 views
9

std::vector이 기본 클래스 인 boost::shared_ptr 인 상황에 직면하고 있습니다. 내 프로그램을 진행하는 동안 해당 벡터에 파생 클래스 객체에 공유 포인터를 저장해야하고 나중에 프로그램에서 나중에 공유 포인터를 검색해야합니다. 코드에 따라boost :: shared_ptr 및 상속

내 문제 설명 : 나는

Derived1Ptr d11 = dynamic_cast<Derived1Ptr>(bPtr); 

Derived1& d11 = dynamic_cast< Derived1& >(*bPtr); 

에서 BOOST_FOREACH의 코드를 변경하는 경우, 위의 코드에서

#include <iostream> 
#include <vector> 
using namespace std; 

#include <boost/make_shared.hpp> 
#include <boost/foreach.hpp> 

class Base 
{ 
public: 
    virtual ~Base() 
    { 
    } 
}; 
/******************************************/ 

typedef boost::shared_ptr<Base> BasePtr; 
/******************************************/ 

class Derived1 : public Base 
{ 
public: 
    void derived1_test() 
    { 
     cout << "derived1_test" << endl; 
    } 
    /******************************************/ 
    int i1; 
}; 
/******************************************/ 

typedef boost::shared_ptr<Derived1> Derived1Ptr; 
/******************************************/ 

class Derived2 : public Base 
{ 
public: 
    void derived2_test() 
    { 
     cout << "derived2_test" << endl; 
    } 
    /******************************************/ 
    int i2; 
}; 
/******************************************/ 

typedef boost::shared_ptr<Derived2> Derived2Ptr; 
/******************************************/ 

int main() 
{ 
    Derived1Ptr d1 = boost::make_shared<Derived1>(); 
    Derived2Ptr d2 = boost::make_shared<Derived2>(); 

    vector<BasePtr> v; 
    v.push_back(d1); 
    v.push_back(d2); 
    BOOST_FOREACH(BasePtr bPtr, v) 
    { 
     try 
     { 
      Derived1& d11 = dynamic_cast< Derived1& >(*bPtr); 
      d11.derived1_test(); 
     } 
     catch (const std::bad_cast& e) 
     { 
      Derived2& d22 = dynamic_cast< Derived2& >(*bPtr); 
      d22.derived2_test(); 
     } 
    } 
    return 0; 
} 

을, 나는 컴파일 다음 얻을 VS2010의 시간 오류

invalid target type for dynamic_cast target type must be a pointer or reference to a defined class 

내 문제는 참조 번호가없는 boost::shared_ptr으로 작업하고 싶습니다. 둘째, 난 dynamic_caststd::bad_cast 예외를 던질 것입니다 개체 참조가 다른 유형 (공유 포인터를 사용하여 그것을 시도했지만 이전에 언급 한 컴파일러 오류를 얻을 때 예외). 그것은 분명히 매우 느립니다. 나는보다 성능 지향적 인 접근법을 사용할 수 있기를 원한다. 내가 여기서 찾고있는 것은 dynamic_cast 및 예외 처리를 사용하는 대신 모든 솔루션입니다.

코드에 대한 제안이나 디자인 변경은 환영합니다. dynamic_pointer_cast

+0

파생 클래스가 하나뿐이거나 유형이 확실한 경우에는 downcast에'static_cast'를 사용할 수 있습니다. – JohnPS

+0

사실 이것은 훨씬 간단한 버전입니다. 실제 코드에는 3 가지 파생 클래스가 있습니다. –

+0

그리고 평범한 포인터가 아니라'shared_ptr'을 사용하고 있다는 것을 깨달았습니다. – JohnPS

답변

13

를 사용하여, 당신은 boost::ptr_vector를 사용하여 더 나을 것입니다.

+0

바로 그게 내가 찾고있는 것입니다. 감사. –

2

하여 벡터 개체를 소유하고 있다면

7

디자인에 요점이없는 것 같습니다. 다형성을 얻기 위해서는 virtual 함수를 사용하는 것이 좋습니다. 제대로

사용 상속 (다형성) :

#include <iostream> 
#include <vector> 
using namespace std; 

#include <boost/make_shared.hpp> 
#include <boost/foreach.hpp> 

class Base 
{ 
public: 
    virtual ~Base() {} 
    virtual void test() = 0; 
}; 
/******************************************/ 

typedef boost::shared_ptr<Base> BasePtr; 
/******************************************/ 

class Derived1 : public Base 
{ 
public: 
    void test() 
    { 
     cout << "derived1_test" << endl; 
    } 
    /******************************************/ 
    int i1; 
}; 

class Derived2 : public Base 
{ 
public: 
    void test() 
    { 
     cout << "derived2_test" << endl; 
    } 
    /******************************************/ 
    int i2; 
}; 

int main() 
{ 
    BasePtr d1 = boost::make_shared<Derived1>(); 
    BasePtr d2 = boost::make_shared<Derived2>(); 

    vector<BasePtr> v; 
    v.push_back(d1); 
    v.push_back(d2); 
    BOOST_FOREACH(BasePtr &bPtr, v) // I use a reference here for efficiency. 
    { 
     bPtr->test(); 
    } 
    return 0; 
} 
1

당신은 몇 가지 옵션이 있습니다! 즉 파생 클래스에서 구현하는 기본 클래스의 순수 가상 메서드를 정의합니다. 또한 각 파생 된 형식에 대해 여분의 shared_ptr 형식이 중복됩니다.

변형 형식을 사용하여 모든 파생 형식을 보관합니다 (제한된 집합). 다이나믹 캐스트가 필요하지 않습니다. 필요한 것을 수행 할 방문자를 지정할 수 있습니다.

관련 문제