muduo中回调函数的生命周期管理

muduo中的回调函数模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_BASE_WEAKCALLBACK_H
#define MUDUO_BASE_WEAKCALLBACK_H

#include <functional>
#include <memory>

namespace muduo
{

// A barely usable WeakCallback

template<typename CLASS, typename... ARGS>
class WeakCallback
{
public:

WeakCallback(const std::weak_ptr<CLASS>& object,
const std::function<void (CLASS*, ARGS...)>& function)
: object_(object), function_(function)
{
}

// Default dtor, copy ctor and assignment are okay

void operator()(ARGS&&... args) const
{
std::shared_ptr<CLASS> ptr(object_.lock());
if (ptr)
{
function_(ptr.get(), std::forward<ARGS>(args)...);
}
// else
// {
// LOG_TRACE << "expired";
// }
}

private:

std::weak_ptr<CLASS> object_;
std::function<void (CLASS*, ARGS...)> function_;
};

template<typename CLASS, typename... ARGS>
WeakCallback<CLASS, ARGS...> makeWeakCallback(const std::shared_ptr<CLASS>& object,
void (CLASS::*function)(ARGS...))
{
return WeakCallback<CLASS, ARGS...>(object, function);
}

template<typename CLASS, typename... ARGS>
WeakCallback<CLASS, ARGS...> makeWeakCallback(const std::shared_ptr<CLASS>& object,
void (CLASS::*function)(ARGS...) const)
{
return WeakCallback<CLASS, ARGS...>(object, function);
}

} // namespace muduo

#endif // MUDUO_BASE_WEAKCALLBACK_H

对于类成员函数注册的回调函数,一定要在该实例的生命周期内调用

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class String
{
public:
String(const char* str)
{
printf("String ctor this %p\n", this);
}

String(const String& rhs)
{
printf("String copy ctor this %p, rhs %p\n", this, &rhs);
}

String(String&& rhs)
{
printf("String move ctor this %p, rhs %p\n", this, &rhs);
}
};

class Foo : boost::noncopyable
{
public:
void zero();
void zeroc() const;
void one(int);
void oner(int&);
void onec(int) const;
void oneString(const String& str);
void oneStringRR(String&& str);
};

BOOST_AUTO_TEST_CASE(testWeakCallback)
{
printf("======== testWeakCallback \n");
std::shared_ptr<Foo> foo(new Foo);
muduo::WeakCallback<Foo> cb0 = muduo::makeWeakCallback(foo, &Foo::zero);
muduo::WeakCallback<Foo> cb0c = muduo::makeWeakCallback(foo, &Foo::zeroc);
cb0();
cb0c();

muduo::WeakCallback<Foo, int> cb1 = muduo::makeWeakCallback(foo, &Foo::one);
auto cb1c = muduo::makeWeakCallback(foo, &Foo::onec);
auto cb1r = muduo::makeWeakCallback(foo, &Foo::oner);
cb1(123);
cb1c(234);
int i = 345;
cb1r(i);
BOOST_CHECK_EQUAL(i, 1000);

auto cb2 = muduo::makeWeakCallback(foo, &Foo::oneString);
auto cb2r = muduo::makeWeakCallback(foo, &Foo::oneStringRR);
printf("_Z%s\n", typeid(cb2).name());
printf("_Z%s\n", typeid(cb2r).name());
cb2(String("xx"));
cb2r(String("yy"));

muduo::WeakCallback<Foo> cb3(foo, std::bind(&Foo::oneString, std::placeholders::_1, "zz"));

cb3();

printf("======== reset \n");
foo.reset(); // 下面函数都无法执行
cb0();
cb0c();
cb1(123);
cb1c(234);
cb2(String("xx"));
cb2r(String("yy"));
cb3();
}