指向具有移动语义的成员函数的指针

pointers to member functions with move semantics

当您有一个指向 堆栈 上对象的非静态成员函数的指针时,当对象因移动而改变其位置时究竟会发生什么?指针是否仍指向移出对象的位置,因此是 invalid/dangling?

一个对象不会“改变它的位置”。当移动发生时,被移动的对象的状态被转移,使用一些未指定的机制(由对象的移动构造函数或移动赋值运算符控制),到被移动到的对象。被移动的对象继续正常存在,处于某种有效但未指定的状态。

一个简单的例子是std::vectorstd::vector 的移动语义的经典实现涉及交换向量内容的内部指针和大小。在过程结束时,moved-from 向量是一个有效的 std::vector,其内容为 moved-to 向量(moved-to 向量的内容为 moved-from向量)。

如果您有一个指向 moved-from 对象的指针,该指针仍指向该对象,处于某种有效但未指定的状态。这种情况一直存在,直到被移动的对象被实际销毁。对于自动作用域中的对象,当它正常发生时,当执行线程离开自动对象的作用域时,就会发生这种情况。发生这种情况时,您会留下一个悬空指针,这与任何其他情况都没有什么不同,其他情况下您会留下一个指向不再存在的对象的悬空指针。

When you have a pointer to a non-static member function of an object on the stack,

您不能拥有指向特定对象成员函数的指针。以下是无效的,不会编译:

struct obj {
  void f();
};
void func()
{
    obj o;
    using func_ptr = void (obj::*)();
    f_ptr pointer_to_o_f = &o::f; // Error
}

指向成员函数的指针不包含对 class 的任何实例的引用。即使对于指向 non-static 成员函数的指针也是如此。

这样的指针可以在没有 class:

实例的情况下构造
class star {
public:
    void shine();
};

void (star::* smile)() = &sun::shine;

并且调用时需要指定一个实例:

star sun;

(sun.*smile)();
std::memfn(smile)(sun);