You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移动含std::bind绑定this成员函数的C++对象?

问题描述

我在类中通过std::bind将成员函数绑定到当前对象的this指针,代码如下:

class SubObject {
  public:
    SubObject(std::function<void()> handler) : _handler(handler) { }
  private:
    std::function<void()> _handler;
};

class A {
  public:
    A(): _sub_object(std::bind(&A::wrapper, this)) { }
  private:
    SubObject _sub_object;
    void wrapper() { /* ... */ }
};

当我给类A添加移动构造函数时,发现传入SubObject的绑定函数无法正常工作——因为它绑定的是原对象的this指针,移动后原对象的this已经失效:

A(A&& other) {
  std::swap(other._sub_object, _sub_object);
}

请问能否移动通过std::bind绑定this生成的函数?

解决方案

直接移动这种绑定了原对象this的std::function行不通,因为std::bind会把this指针固定绑定到原对象的地址,移动操作不会自动更新这个指针。要解决这个问题,有几种实用思路:

1. 改用智能指针动态获取当前对象

让A继承std::enable_shared_from_this,用lambda捕获shared_from_this()来替代std::bind,这样调用时会自动获取当前对象的有效指针:

#include <memory>

class A : public std::enable_shared_from_this<A> {
public:
    A(): _sub_object([this]() {
        if (auto self = shared_from_this()) {
            self->wrapper();
        }
    }) { }
    
    A(A&& other) noexcept {
        std::swap(other._sub_object, _sub_object);
    }

private:
    SubObject _sub_object;
    void wrapper() { /* ... */ }
};

这种方式下,即使对象被移动,lambda调用时拿到的self始终是当前有效对象的指针,不会指向已失效的原对象。

2. 移动时重新绑定当前this

如果一定要用std::bind,不要直接交换_sub_object,而是在移动构造时为新对象重新创建绑定自身this的函数:

A(A&& other) noexcept 
    : _sub_object(std::bind(&A::wrapper, this)) {
    // 可选:将原对象的handler置空,避免无效调用
    other._sub_object = SubObject(nullptr);
}

相当于抛弃原对象的旧绑定,给新对象生成一个全新的、指向自身的绑定函数,确保调用时指向正确实例。

3. 给SubObject加更新handler的接口

给SubObject添加成员函数来更新内部存储的std::function,移动时先交换对象,再手动更新handler为绑定当前this的版本:

class SubObject {
public:
    SubObject(std::function<void()> handler) : _handler(std::move(handler)) { }
    
    void updateHandler(std::function<void()> new_handler) {
        _handler = std::move(new_handler);
    }

private:
    std::function<void()> _handler;
};

class A {
public:
    A(): _sub_object(std::bind(&A::wrapper, this)) { }
    
    A(A&& other) noexcept {
        std::swap(other._sub_object, _sub_object);
        // 更新handler为绑定当前this的版本
        _sub_object.updateHandler(std::bind(&A::wrapper, this));
    }

private:
    SubObject _sub_object;
    void wrapper() { /* ... */ }
};

内容的提问来源于stack exchange,提问作者Stefan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:50:26