2

here is a "chess++" problem that I'm facing wright now with my nested class, although it may look like some joke, it's not a joke but real problem which I want to either solve or change the way to achieve the same thing in my project.

#include <map>
#include <memory>
#include <iostream>
#include <sigc++/signal.h>

class foo
{
public:
    struct bar;

    typedef sigc::signal<void, std::shared_ptr<bar>> a_signal;

    struct bar
    {
        bar()
        {
            some_signal.connect(sigc::mem_fun(*this, &foo::bar::func));
        }

        void notify()
        {
            some_signal.emit(this); // how to ??
        }

        void func(std::shared_ptr<foo::bar> ptr)
        {
            std::cout << "you haxor!" << std::endl;
            // use the pointer ptr->
        }

        a_signal some_signal;
    };

    std::map<int, std::shared_ptr<bar>> a_map;
};

int main()
{
    std::shared_ptr<foo::bar> a_foo_bar;
    foo foo_instance;

    foo_instance.a_map.insert(std::pair<int, std::shared_ptr<foo::bar>>(4, a_foo_bar));
    foo_instance.a_map.at(0)->notify();
    return 0;
}

What I want to do here is to emit a signal. the signal is declared as one that triggers a handler that takes a shared_ptr as an argument. the function notify() should convert *this into shared_ptr, how do I do that to make the above code run?

codekiddy
  • 5,897
  • 9
  • 50
  • 80
  • 3
    std::shared_from_this – Sneftel Jul 25 '14 at 13:20
  • possible duplicate of [Getting a boost::shared\_ptr for this](http://stackoverflow.com/questions/142391/getting-a-boostshared-ptr-for-this) – Sneftel Jul 25 '14 at 13:21
  • [Reference for said function](http://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this) (note your class has to inherit from the appropriate class) – chris Jul 25 '14 at 13:23

1 Answers1

3

Derive from enable_shared_from_this:

struct bar : std::enable_shared_from_this<bar>

to get a member shared_from_this():

some_signal.emit(shared_from_this());

As long as the current object is owned by at least one shared pointer, this will return a shared pointer, sharing ownership with that pointer. Note that, in your program, a_foo_bar is empty, so neither this nor the call to notify will work. Also beware that it won't work from the constructor or destructor, since the object is not owned by a shared pointer at that time.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    Note that if the current object is *not* owned by a `shared_ptr`, `shared_from_this()` will *throw*. So it would probably be a good idea to hide `bar`'s constructor and instead expose a static factory method that returns `std::shared_ptr` so you can guarantee that all instances will be in `shared_ptr`s. – dlf Jul 25 '14 at 13:37
  • 1
    @dlf: Worse than that: if it's not owned by a shared pointer, then you get undefined behaviour. (The example implementation given in the standard, storing a weak pointer, would throw `bad_weak_ptr`, but there's no requirement to use that implementation). – Mike Seymour Jul 25 '14 at 13:45