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

调用移动对象的成员函数是否可行?下述代码是否存在危险或未定义行为?

你的代码安全吗?拆解细节与风险边界

没问题,这段代码不存在未定义行为,但咱们得把核心逻辑和潜在注意点掰扯清楚:

先搞懂std::swap在这里的实际行为

你调用的std::swap(arr[i], arr[arr.size()-1]),交换的是vector里两个Bar元素的内容,而非元素的内存位置。vector的元素存在连续内存块里,只要不触发扩容(这里vector大小没变,肯定不会扩容),每个元素的内存地址是固定的——说白了,就是把两个Bar的x和parent成员互换了位置,对象本身在内存里的“座位”没动。

跟着调用链走一遍,看哪里会出问题?

咱们一步步捋:

  1. 你通过foo.arr[3].trigger(3)调用trigger,此时函数里的this指针指向foo.arr[3]的内存地址。
  2. trigger内部调用parent->moveBack(3),moveBack执行swap操作:
    • 这时候foo.arr[3]这个地址上的对象内容,已经被换成了原来最后一个Bar的内容,但this指针还是死死盯着这个地址。
  3. 但关键来了:你的trigger函数在调用完moveBack之后就直接返回了,再也没碰过this或者当前对象的任何成员。所以哪怕这个地址的对象内容被替换了,也不会有任何问题——因为我们已经用不上它了。

什么时候会踩坑?扩展逻辑时要注意

如果后续你给trigger加了代码,比如swap之后还要访问当前对象的成员:

void Bar::trigger(size_t i) {
    parent->moveBack(i);
    std::cout << this->x << std::endl; // 这里输出的是原来最后一个Bar的x,不是当前对象原本的x!
}

这时候会出现逻辑错误(不是未定义行为),因为此时this指向的foo.arr[3]已经是另一个Bar的内容了。但你现在的代码里没有这个情况,所以完全安全。

关于“对象移动自身”的小误解

你提到“本质上是Bar类型的对象在移动自身”,其实更准确的说法是:对象的内容被交换到了vector的最后一个位置,而对象的内存地址(也就是this指向的位置)根本没动。vector的元素不会因为swap换座位,换的只是座位上的“乘客”(成员值)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:13:59