boost::shared_ptr 和继承

发布于 2024-10-20 09:39:18 字数 2478 浏览 5 评论 0原文

我面临的情况是,我有一个基类的 boost::shared_ptrstd::vector 。在我的程序过程中,我也需要在该向量中存储指向派生类对象的共享指针,并且在程序稍后的某个时间,需要检索这些共享指针。

以下代码说明了我的问题:

#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 和异常处理。

欢迎提出有关代码或设计更改的任何建议。

I am facing a situation in which I have a std::vector of boost::shared_ptrs of a base class. During the course of my program I need to store shared pointers to derived class objects in that vector too and at some time later in the program, need to retrieve those shared pointers.

Following code illustrates my problem:

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

In the above code, if I change the code in BOOST_FOREACH from

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

to

Derived1Ptr d11 = dynamic_cast< Derived1Ptr >( bPtr );

, I get following compile time error on VS2010

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

My problem is that I want to work with boost::shared_ptr not references. Secondly, I am using dynamic_cast which will throw a std::bad_cast exception when object reference is of a different type (tried using it with shared pointers but get the compiler error mentioned previously). That is clearly very slow. I want to be able to use a more performance oriented approach. What I am looking for here is any solution instead of using dynamic_cast and exception handling.

Any suggestion with regards to code or change in design are welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风启觞 2024-10-27 09:39:18

你的设计似乎没有抓住要点;最好使用虚拟函数来实现多态行为。

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

Your design seems to be missing the point; it would be better to use virtual functions to achive polymorphic behaviour.

#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;
}
眼泪也成诗 2024-10-27 09:39:18

如果你的向量拥有这些对象,你最好使用 boost::ptr_vector

If your vectors own the objects, you would be better off using a boost::ptr_vector.

予囚 2024-10-27 09:39:18

您有多种选择:

正确使用继承(和多态性)!即在基类中定义纯虚方法,并在派生类中实现该方法(此外,每个派生类型的额外 shared_ptr 类型是多余的!)

使用变体类型来保存所有派生类型(如果你的套装有限)。那么就不需要动态转换,您可以指定一个访问者来执行您需要的操作。

You have several options:

Use inheritance (and polymorphism) properly! i.e. define pure virtual methods in your base class which you implement in your derived class (also, the extra shared_ptr type for each derived type is redundant!)

Use a variant type to hold all derived types (useful if you have a limited set). There is no need for dynamic cast then, you can specify a visitor to do what you need to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文