2017-10-18 110 views
1

可以说我有以下几点:成员函数何时超出范围?

struct Foo 
{ 
    Foo() : bar([&]{ doSomething();}) 
    std::function<void(void)> bar; 
    void doSomething(){}; 
} 

而且可以说,一个线程调用经常一个Foo实例的杆件,而另一个线程自毁foo的实例。因为Foo的析构函数被首先调用,所以调用bar会导致无效的函数调用吗?在释放之前,Foo的析构函数是否使无效的成员函数调用?

编辑: 对不起,我应该有一个更具体一点,调用doSomething成为未定义之前bar的析构函数被调用?

+0

成员变量存在于对象中。如果没有对象,那么成员变量如何存在? –

+2

这是你的责任,以确保没有线程破坏一个对象,而另一个线程是或可能正在使用它。 –

+0

这就是为什么一个对象无法同步其自身的破坏的主要原因。如果你想实现'销毁请求',也就是说,一个对象可以被请求在同时处理其他请求的同时被破坏,这必须在*外部*,而不是由类本身同步。 – ComicSansMS

回答

0

成员函数保持有效,直到对象有效。当对象被销毁时,成员函数也被销毁,并且当调用析构函数时对象被销毁。因此,析构函数中的调用使成员函数失效。而且如果在对象销毁后调用成员函数会导致未定义的行为。所以,你需要确保在对象被销毁后没有成员函数被调用。

3

由于Foo的析构函数被首先调用,调用bar会导致无效的函数调用吗?

是的,除非你确定没有发生。

Foo的析构函数在释放之前调用invalidate成员函数吗?

是的。只要析构函数被调用,对该对象及其子对象的所有引用就会失效。

请注意,成员函数与您有什么不同。你有什么是一个成员对象的函数包装器。虽然这个区别对答案没有任何影响。

+0

澄清:*无效*这意味着它在析构函数启动后立即执行成员函数不再有效。该语言实际上并没有强制执行此操作。确保这绝不会发生的是你的责任。如果你没有正确地做到这一点,该程序可以炸毁你的脸。 – ComicSansMS