Chromium Base学习笔记 —— Callback

来源:互联网 发布:台北代表处 知乎 编辑:程序博客网 时间:2024/06/05 06:32

Callback对象在传递过程中,必须是const-reference类型。


基本用法如下:

int Return5() { return 5; }base::Callback<int(void)> func_cb = base::Bind(&Return5);LOG(INFO) << func_cb.Run();  // Prints 5.

绑定类方法:

绑定类方法的时候,该Class必须继承自RefCounted。如果需要在Thread中传递,那么需要保证线程安全(RefCountedThreadSafe)

   class Ref : public base::RefCountedThreadSafe<Ref> {    public:     int Foo() { return 3; }     void PrintBye() { LOG(INFO) << "bye."; }   };   scoped_refptr<Ref> ref = new Ref();   base::Callback<void(void)> ref_cb = base::Bind(&Ref::Foo, ref);   LOG(INFO) << ref_cb.Run();  // Prints out 3.// MISSING FUNCTIONALITY//  - Binding arrays to functions that take a non-const pointer.//    Example://      void Foo(const char* ptr);//      void Bar(char* ptr);//      Bind(&Foo, "test");//      Bind(&Bar, "test");  // This fails because ptr is not const.

使用Run方法运行:

void DoSomething(const base::Callback<void(int, std::string)>& callback) {    callback.Run(5, "hello");}// 可以重复使用Callback:void DoSomething(const base::Callback<double(double)>& callback) {  double myresult = callback.Run(3.14159);  myresult += callback.Run(2.71828);}

1. PASSING UNBOUND INPUT PARAMETERS

void MyFunc(int i, const std::string& str) {}base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);cb.Run(23, "hello, world");

2. PASSING BOUND INPUT PARAMETERS

void MyFunc(int i, const std::string& str) {}base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world");cb.Run();//A callback with no unbound input parameters (base::Callback<void(void)>)//is called a base::Closure. So we could have also written:base::Closure cb = base::Bind(&MyFunc, 23, "hello world");//   When calling member functions, bound parameters just go after the object//   pointer.//base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");

3. PARTIAL BINDING OF PARAMETERS

   void MyFunc(int i, const std::string& str) {}   base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);   cb.Run("hello world");

高级用法:

1. 通过WeakPtr绑定类方法:不是线程安全的,只能在单线程中使用

base::Bind(&MyClass::Foo, GetWeakPtr());

2. 手动管理This的声明周期,也就是this的拥有权不归Callback所有

base::Bind(&MyClass::Foo, base::Unretained(this));

3. 与2相反,This指针归Callback所有,Callback被destroy的时候,this也会被delete掉。

//   MyClass* myclass = new MyClass;
//   base::Bind(&MyClass::Foo, base::Owned(myclass));

4. 忽略返回值的情况

int DoSomething(int arg) { cout << arg << endl; }
base::Callback<void<int>) cb =
     base::Bind(base::IgnoreResult(&DoSomething));


Quick reference for binding parameters to Bind():

关于Closure:A callback with no parameters or no unbound parameters is called a Closure (base::Callback<void(void)> and base::Closure are the same thing).

(1)With No Parameters:

base::Callback<void(void)>

(2)No Unbound Parameters:

void MyFunc(int i, const std::string& str) {}base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world");cb.Run();

PASSING PARAMETERS OWNED BY THE CALLBACK:

void Foo(int* arg) { cout << *arg << endl; }int* pn = new int(1);base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));//   The parameter will be deleted when the callback is destroyed, even if it's//   not run (like if you post a task during shutdown).

PASSING PARAMETERS AS A scoped_ptr:

void TakesOwnership(scoped_ptr<Foo> arg) {}scoped_ptr<Foo> f(new Foo);// f becomes null during the following call.base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f));//   Ownership of the parameter will be with the callback until the it is run,//   when ownership is passed to the callback function. This means the callback//   can only be run once. If the callback is never run, it will delete the//   object when it's destroyed.//     arg的生命周期是TakesOwnership的函数执行结束
PASSING PARAMETERS AS A scoped_refptr:

void TakesOneRef(scoped_refptr<Foo> arg) {}scoped_refptr<Foo> f(new Foo)base::Closure cb = base::Bind(&TakesOneRef, f);//   This should "just work." The closure will take a reference as long as it//   is alive, and another reference will be taken for the called function.

PASSING PARAMETERS BY REFERENCE:

//   Const references are *copied* unless ConstRef is used. Example://void foo(const int& arg) { printf("%d %p\n", arg, &arg); }int n = 1;base::Closure has_copy = base::Bind(&foo, n);base::Closure has_ref = base::Bind(&foo, base::ConstRef(n));n = 2;foo(n);                        // Prints "2 0xaaaaaaaaaaaa"has_copy.Run();                // Prints "1 0xbbbbbbbbbbbb"has_ref.Run();                 // Prints "2 0xaaaaaaaaaaaa"//   Normally parameters are copied in the closure. DANGER: ConstRef stores a//   const reference instead, referencing the original parameter. This means//   that you must ensure the object outlives the callback!//   ConstRef存储的是参数的引用,而不是参数的拷贝。所以使用ConstRef要确保Run()之前参数是有效的。





原创粉丝点击