2011-03-03 108 views
9

我面临的情况是我有一个std::vectorboost::shared_ptr s基类。在我的程序过程中,我需要在该向量中存储指向派生类对象的共享指针,并且在稍后的程序中,需要检索这些共享指针。boost :: shared_ptr和Inheritance

下面的代码说明我的问题:

#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; 
} 

在上面的代码,如果我在BOOST_FOREACH代码从

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

改变

Derived1Ptr d11 = dynamic_cast<Derived1Ptr>(bPtr); 

,我获得以下编译VS2010上的时间错误

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

我的问题是我想使用boost::shared_ptr而不是引用。其次,我使用的是dynamic_cast,如果对象引用是不同类型的(尝试使用它与共享指针但得到前面提到的编译器错误),则会引发std::bad_cast异常。这显然非常缓慢。我希望能够使用更加注重性能的方法。我在这里寻找的是任何解决方案,而不是使用dynamic_cast和异常处理。

任何关于代码或设计更改的建议都是受欢迎的。

+0

如果只有一个派生类,或者您确定它是类型的,您可以使用'static_cast'来向下转换。 – JohnPS 2011-03-03 13:40:26

+0

其实这是一个更简单的版本。在实际的代码中有3个不同的派生类。 – 2011-03-03 13:45:30

+0

我意识到你使用'shared_ptr'不是纯指针,所以不理睬我的建议。 – JohnPS 2011-03-03 13:47:35

回答

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类型都是多余的!)

使用变体类型来保存所有派生类型(如果您有有限套)。这样就不需要动态演员了,你可以指定一个访问者来做你需要的东西。

相关问题