Object API 文档

概述

mc::object 是 mcbase 的对象基类,提供名称、父子层次、事件传播、连接跟踪与执行器调度能力。

主要特性

  • 拥有所有权的名称快照:get_name() 在读锁内返回 COW mc::string,不借用对象内部存储
  • 父子生命期管理:父对象保存子对象强引用,子对象保存父对象弱引用
  • 事件传播:支持同步发送、异步投递和父链过滤
  • 连接自动清理:通过对象 connect() 建立的连接随对象析构断开
  • 执行器路由:可绑定独占 executor,或从对象组与父链继承执行器

基本用法

设置名称并保留快照

#include <mc/object.h>
#include <cassert>

int main()
{
    mc::object object;
    object.set_name("sensor");
    mc::string name = object.get_name();
    assert(name == "sensor");
    return 0;
}

建立父子关系

#include <mc/object.h>
#include <cassert>

int main()
{
    auto parent = mc::make_shared<mc::object>();
    auto child = mc::make_shared<mc::object>();
    parent->set_name("parent");
    child->set_name("child");
    child->set_parent(parent);
    assert(child->get_parent() == parent);
    assert(parent->find_child("child") == child);
    return 0;
}

取得子对象列表快照

#include <mc/object.h>
#include <cassert>

int main()
{
    auto parent = mc::make_shared<mc::object>();
    auto first = mc::make_shared<mc::object>();
    auto second = mc::make_shared<mc::object>();
    first->set_name("first");
    second->set_name("second");
    first->set_parent(parent);
    second->set_parent(parent);

    mc::child_list children = parent->get_children();
    assert(children.size() == 2);
    return 0;
}

API 详细说明

mc::object

方法 参数 返回值 异常 线程安全 说明
object() / object(object* parent) 可选父对象 对象实例 内存分配失败时抛 std::bad_alloc 构造期独占 创建对象,可同时建立父子关系
get_name() const 无 mc::string 内存分配失败时抛 std::bad_alloc 是 在读锁内取得 COW 名称快照;返回值不依赖对象生命期
set_name(name) mc::string_view name void 名称已设置时断言失败;分配失败时抛 std::bad_alloc 是 业务名称只允许设置一次
_reset_name_for_rollback(name) mc::string_view name void 分配失败时抛 std::bad_alloc 是 仅供框架事务回滚恢复名称,业务代码不要调用
get_parent() const 无 object_ptr 不抛出 是 返回父对象强引用;无父对象时为空
set_parent(parent) object* 或 mc::shared_ptr<T> void 非法所有权或分配失败时抛出 是 从旧父对象摘除并加入新父对象
get_children() const 无 child_list 分配失败时抛 std::bad_alloc 是 返回子对象强引用列表快照
find_child(name) const mc::string_view name object_ptr 不抛出 是 按名称查找直接子对象
send_event(event) mc::event& void 事件处理器异常向外传播 调用方串行 同步发送事件并沿对象链传播
post_event(event[, priority]) std::shared_ptr<mc::event>、可选优先级 void 投递失败时抛出 是 向对象 executor 异步投递事件
delete_later() 无 void 投递失败时抛出 是 在对象 executor 上安排延迟清理,重复调用幂等
install_event_filter(filter[, priority]) event_filter_handler、可选优先级 mc::connection 分配失败时抛出 是 安装对象事件过滤器
connect(signal, slot[, mode/priority/executor]) signal、slot 与投递选项 mc::connection_type 非 void 信号使用非 Direct 模式时断言失败;连接失败时抛出 是 建立并自动跟踪连接
post(token) / defer(token) / dispatch(token) 完成令牌与可选 allocator 由令牌决定 executor 拒绝任务时抛出 是 通过对象当前 executor 调度任务
bind_executor(exec) executor_type void 移动或分配失败时抛出 是 给当前对象绑定独占 executor
executor() const 无 executor_type 无可用 executor 时抛出 是 按自身、group、父链、全局的顺序解析 executor
set_group(group) object* void 非法所有权时抛出 是 将对象加入共享 executor 的调度组
get_group() const 无 object_ptr 不抛出 是 返回调度组强引用
is_executor_bound() const 无 bool 不抛出 是 判断当前对象是否显式绑定 executor
shared_from_this() 无 object_ptr 对象未由 mc::shared_ptr 管理时抛出 是 返回当前对象强引用
weak_from_this() const 无 mc::weak_ptr 不抛出 是 返回当前对象弱引用
on_event(event) mc::event& void 默认实现不抛出;覆写实现决定 由调用方保证 可覆写的事件处理入口
dispatch_event_filters(child, event) 子对象与事件 bool filter 异常向外传播 由调用方保证 执行事件过滤器并返回是否继续传播
read_parent_anchor() const 无 object_ptr 不抛出 是 读取"作为 parent 时的锚点":锚点未设置或挂链时刻弱锁定失败(宿主尚未纳入引用管理/已失效)返回空;仅跟随一跳。框架装配路径写入,对 ref 管理对象恒为空
set_parent_anchor(anchor)(protected) object* anchor void 不抛出 是 写入父锚点(宿主裸指针)。约束:anchor 须覆盖本对象整个生命周期(interface 值成员与宿主的成员关系天然满足,接口析构时清空);仅支持一层(接口→宿主),不支持嵌套锚点或锚点成环
suspend_parent_hold()(protected) 无 void 不抛出 是(幂等) 摘除父对象对本对象的强持有,保留弱血缘;get_parent 与 executor 父链解析不受影响;无父对象调用为空操作且不改标志。调用方必须持有本对象强引用(最后一个强引用在 children 中时摘除会在父锁内析构自身并死锁)
resume_parent_hold()(protected) 无 void 不抛出 是(幂等) 与 suspend 配对恢复父对象强持有;父对象已析构或删除流程中跳过;挂起态由 resume 或显式 set_parent 终结(后者直接恢复基类挂链语义)

最佳实践

✅ 保存按值返回的名称快照

mc::string name = object.get_name();
// 即使对象随后改名、回滚或析构,name 仍然有效。

✅ 用智能指针建立父子关系

auto parent = mc::make_shared<mc::object>();
auto child = mc::make_shared<mc::object>();
child->set_parent(parent);

❌ 不要为名称返回值增加线程局部中转

// 错误:get_name() 已返回拥有所有权的 COW 字符串。
static MC_THREAD_LOCAL mc::string cache;
cache = object.get_name();

❌ 不要在业务代码中调用回滚接口改名

// 错误:该接口只用于框架事务补偿。
object._reset_name_for_rollback("new-name");

set_parent

  • set_parent 父锚点归一化:传入对象带有父锚点(见 object::set_parent_anchor, 目前由 mc::engine::interface_impl::set_owner 在装配期写入)且锚点有效时, 实际挂靠锚点对象;锚点为空/失效时保持传入对象(旧语义)。锚点为弱引用, 宿主存活期内锁定成功才生效,不会引用已析构对象。