繁体   English   中英

如何保证对象的寿命与成员函数的持续时间匹配?

[英]How can I guarantee an object's lifespan matches the duration of a member function?

我一直在使用回调来减少某些C ++类之间的耦合。 定义术语:我将调用回调的类称为调用者,将接收回调的类称为被调用者。 通常(但不是必须),被呼叫者将拥有呼叫者。 通过设计,呼叫者不了解被呼叫者。

我遇到了一个与调用者对象的生命周期有关的问题:它不能保证在进行任何任意回调后它仍然会存在。 举个基本的例子:

void caller::f()
{
    /* Some work */
    if (...)
    {
        /* [1] Execute callback */
        _callee->callback(this);
    }
    /* [2] Some more work */
}

假设被呼叫者已经动态分配了呼叫者,并已专门为回调注册以等待特定条件的发生。 完成后,被叫方将从[1]的回调中删除该呼叫者。 如果是这样的情况下,控制可能会返回主调::女,但this已经被删除了,并且在任何代码[2]将很可能崩溃。

在一般情况下,呼叫者无法承担有关被呼叫者的任何事情。 它不知道被调用方是否拥有this ,或者它是否可能取消分配this ,因此我将需要一些常规方法来防止在调用方成员函数的作用域内重新分配。

我相信可能的解决方案围绕boost::shared_ptrsenable_shared_from_this ,尽管我从未使用过。 由于这些回调在处理能力有限的移动设备上非常频繁地运行(每秒40次以上),因此我也担心创建和shared_ptrs许多shared_ptrs的开销。

委派是Objective-C中非常常见的模式。 我对常见的C ++设计模式不太熟悉。 是否有解决此问题的简便方法? 如果没有,通常如何在C ++中完成这种设计?

当被调用方delete s调用方时,将调用调用方的析构函数。 在此应确保f已完成。

我猜f是一个线程,所以最简单的解决方案是:

线:

running = true;
while (!must_exit)
    /* do something */

解构器:

thread->must_exit = true;
while (thread->running)
    sleep(a_little);
/* continue with destruction */

如果f不是线程,则在f使其对象(并通过其析构函数)知道何时运行以及何时不运行的情况下,可以应用相同的原理。


如果您不希望使用析构方法,则仍可以通过被调用方调用的函数来实现此功能,告诉f再也不要运行,直到它停止为止。 然后,被叫方继续删除呼叫者。

所以像这样:

void caller::f()
{
    if (being_deleted)
        return;
    running = true;
    /* Some work */
    if (...)
    {
        /* [1] Execute callback */
        _callee->callback(this);
    }
    /* [2] Some more work */
    running = false;
}

void caller::make_f_stop()
{
    being_deleted = true;
    while (running)
        sleep(a_little);
}

继续并使用共享指针,尽管可能的话,请使用std::shared_ptr而不是boost::shared_ptr 它在(当前)标准库中,因此无需添加不必要的boost依赖项。 如果您已经在使用boost,那也很好。

您没有指定要谈论的移动设备类型,但是现代智能手机中的处理器运行速度高达数百或数千兆赫兹,甚至低功率手机也经常运行Java程序(带有垃圾回收)就可以了。 共享指针基本上是引用计数。 这不是资源密集型活动。

如果您的设备每秒可以实际运行回调超过40次,那么我怀疑共享指针是否会带来麻烦。 不要过早地优化执行速度。 请过早优化安全性和卫生性。

绕过不再执行的代码的通常方法是引发异常。 被呼叫者应在删除呼叫者之后通常返回到呼叫者的位置进行此操作。 该函数的末尾将在调用者代码中捕获该异常。

我不能说我喜欢这种解决方案,但我认为这是由于被呼叫者拥有呼叫者的情况异常。

我不知道智能指针将如何提供帮助,因为没有人拥有指针的第二个副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM