问题描述
当您在堆栈上具有指向对象的非静态成员函数的指针时,该对象由于移动而更改其位置时会发生什么?指针是否仍指向移出对象的位置,因此无效/悬空?
解决方法
成员函数的指针不包含对该类任何实例的引用。即使是指向非静态成员函数的指针,也是如此。
这样的指针可以在没有类实例的情况下构造:
class star {
public:
void shine();
};
void (star::* smile)() = &sun::shine;
调用实例时需要指定一个实例:
star sun;
(sun.*smile)();
std::memfn(smile)(sun);
,
对象不会“更改其位置”。发生移动时,使用某种未指定的机制(由对象的move构造函数或move赋值运算符控制)将要从其移动的对象的状态转移到被移动到的对象。被移动的对象继续以某种有效但未指定的状态正常存在。
一个简单的示例是std::vector
。 std::vector
的移动语义的经典实现涉及交换内部指针和向量内容的大小。在此过程结束时,移出向量是有效的std::vector
,其中包含移入向量的内容(移入向量具有移出向量的内容)。>
如果您有一个指向移出对象的指针,则该指针仍会以某种有效但未指定的状态指向该对象。在从其移走的对象实际被销毁之前,情况一直如此。如果对象在自动作用域中,则该情况通常发生在执行线程离开自动作用域的范围之内。发生这种情况时,您将剩下一个悬空指针,这与使您悬空指针指向不再存在的对象的其他情况没有什么不同。
,当您有一个指向堆栈上对象的非静态成员函数的指针时,
您不能具有指向特定对象的成员函数的指针。以下内容无效,将无法编译:
struct obj {
void f();
};
void func()
{
obj o;
using func_ptr = void (obj::*)();
f_ptr pointer_to_o_f = &o::f; // Error
}