• boost bind 表达式中的是值语义还是指针语义?


    bind 表达式中的是值语义还是指针语义?

    当我们传递某种类型的实例给一个 bind 表达式时,它将被复制,除非我们显式地告诉 bind 不要复制它。要看我们怎么做,这可能是至关重要的。为了看一下在我们背后发生了什么事情,我们创建一个 tracer 类,它可以告诉我们它什么时候被缺省构造、被复制构造、被赋值,以及被析构。这样,我们就可以很容易看到用不同的方式使用 bind 会如何影响我们传送的实例。以下是完整的 tracer 类。

    class tracer {
    public:
    tracer() {
    std::cout << "tracer::tracer()\n";
    }

    tracer(const tracer& other) {
    std::cout << "tracer::tracer(const tracer& other)\n";
    }

    tracer& operator=(const tracer& other) {
    std::cout <<
    "tracer& tracer::operator=(const tracer& other)\n";
    return *this;
    }

    ~tracer() {
    std::cout << "tracer::~tracer()\n";
    }

    void print(const std::string& s) const {
    std::cout << s << '\n';
    }
    };

    我们把我们的 tracer 类用于一个普通的 bind 表达式,象下面这样。

    tracer t;
    boost::bind(&tracer::print,t,_1)
    (std::string("I'm called on a copy of t\n"));

    运行这段代码将产生以下输出,可以清楚地看到有很多拷贝产生。

    tracer::tracer()
    tracer::tracer(const tracer& other)
    tracer::tracer(const tracer& other)
    tracer::tracer(const tracer& other)
    tracer::~tracer()
    tracer::tracer(const tracer& other)
    tracer::~tracer()
    tracer::~tracer()
    I'm called on a copy of t

    tracer::~tracer()
    tracer::~tracer() // 译注:原文没有这一行,有误

    如果我们使用的对象的拷贝动作代价昂贵,我们也许就不能这样用 bind 了。但是,拷贝还是有优点的。它意味着 bind 表达式以及由它所得到的绑定器不依赖于原始对象(在这里是 t)的生存期,这通常正是想要的。要避免复制,我们必须告诉 bind 我们想传递引用而不是它所假定的传值。我们要用 boost::refboost::cref (分别用于引用和 const 引用)来做到这一点,它们也是 Boost.Bind 库的一部分。对我们的 tracer 类使用 boost::ref ,测试代码现在看起来象这样:

    tracer t;
    boost::bind(&tracer::print,boost::ref(t),_1)(
    std::string("I'm called directly on t\n"));

    Executing the code gives us this:

    tracer::tracer()
    I'm called directly on t

    tracer::~tracer() // 译注:原文为 tracer::~tracer,有误

    这正是我们要的,避免了无谓的复制。bind 表达式使用原始的实例,这意味着没有 tracer 对象的拷贝了。当然,它同时也意味着绑定器现在要依赖于 tracer 实例的生存期了。还有一种避免复制的方法;就是通过指针来传递参数而不是通过值来传递。

    tracer t;
    boost::bind(&tracer::print,&t,_1)(
    std::string("I'm called directly on t\n"));

    因此说,bind 总是执行复制。如果你通过值来传递,对象将被复制,这可能对性能有害或者产生不必要的影响。为了避免复制对象,你可以使用 boost::ref/boost::cref 或者使用指针语义。

  • 相关阅读:
    C++---拷贝构造函数和赋值构造函数
    C++---类成员变量定义为引用
    从文件处理到文件的高级应用
    Jupyter的使用复习
    字符编码到python编辑器流程
    周四的小结
    中秋前的题目
    三段代码块带走今天的脚本
    今日份的随笔
    明天才能学的运算符号表格
  • 原文地址:https://www.cnblogs.com/ghost240/p/2531282.html
Copyright © 2020-2023  润新知