boost::bind, boost::shared_ptr and inheritance

boost::bind, boost::shared_ptr and inheritance

本文关键字:boost and inheritance ptr shared bind      更新时间:2023-10-16

我是Boost库的新手,遇到了一个对我来说有点复杂的问题。我试图用前面问题中的一个例子来重新表述它,这个例子可能很适合我的问题。(前一个问题在这里)

#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
    : public boost::enable_shared_from_this<Base>,
      private boost::noncopyable
{
public:
        virtual void test() = 0;
protected:
        virtual void foo(int i) = 0;
};
class Derived
    : public Base
{
protected:
    void foo(int i)
    { std::cout << "Base: " << i << std::endl; }
    std::map<int, int> data;
public:     
    Derived()
    {
            data[0] = 5;
            data[1] = 6;
            data[2] = 7;
    }        
    void test()
    {
        std::for_each(data.begin(), data.end(),
            boost::bind(&Derived::foo, shared_from_this(),
                boost::bind(&std::map<int, int>::value_type::second, _1)));
    }
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
    std::set<Base_ptr> Bases_;
    Base_ptr derived(new Derived());
    Bases_.insert(derived);
    derived->test();

    return 0;
}

我有一个包含在集合中的基对象,以及不同的派生对象(在本例中只有一个)。派生对象应该使用boost::bind调用自己的protected方法。在实际问题中,boost::bind为异步操作生成回调方法,这就是(我认为)我需要shared_ptr的原因。否则,使用指针this代替shared_from_this()可以解决这个问题。

当我编译这段代码时,我得到了一个很长的错误消息,以(我认为是最重要的部分)结尾:
bind_test.cpp:43:78:   instantiated from here
/usr/include/boost/bind/mem_fn_template.hpp:156:53: error: pointer to member type ‘void (Derived::)(int)’ incompatible with object type ‘Base’
/usr/include/boost/bind/mem_fn_template.hpp:156:53: error: return-statement with a value, in function returning 'void'

我试图管理更多的继承从enable_shared_from_this,和一些静态强制转换:

#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
    : public boost::enable_shared_from_this<Base>,
      private boost::noncopyable
{
public:
        virtual void test() = 0;
protected:
        virtual void foo(int i) = 0;
};
class Derived
    : public boost::enable_shared_from_this<Derived>,
      public Base
{
protected:
    void foo(int i)
    { std::cout << "Base: " << i << std::endl; }
    std::map<int, int> data;
public:     
    Derived()
    {
            data[0] = 5;
            data[1] = 6;
            data[2] = 7;
    }        
    void test()
    {
        std::for_each(data.begin(), data.end(),
            boost::bind(&Derived::foo, boost::enable_shared_from_this<Derived>::shared_from_this(),
                boost::bind(&std::map<int, int>::value_type::second, _1)));
    }
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
    std::set<Base_ptr> Bases_;
    Base_ptr derived(new Derived());
    Bases_.insert(derived);
    derived->test();

    return 0;
}

但是我在运行时得到了一个错误:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
  what():  tr1::bad_weak_ptr

可能有人有一个关于如何管理的线索吗?谢谢。

艾蒂安。

这个解决方案可以工作,但我不满意,所以如果有人找到更好的解决方案,请继续。

#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
    : public boost::enable_shared_from_this<Base>,
      private boost::noncopyable
{
public:
        virtual void test() = 0;
//protected:
        virtual void foo(int i) = 0;
};
class Derived
    : public Base
{
protected:
    void foo(int i)
    { std::cout << "Base: " << i << std::endl; }
    std::map<int, int> data;
public:     
    Derived()
    {
            data[0] = 5;
            data[1] = 6;
            data[2] = 7;
    }        
    void test()
    {
        std::for_each(data.begin(), data.end(),
            boost::bind(&Base::foo, shared_from_this(),
                boost::bind(&std::map<int, int>::value_type::second, _1)));
    }
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
    std::set<Base_ptr> Bases_;
    Base_ptr derived(new Derived());
    Bases_.insert(derived);
    derived->test();

    return 0;
}