簡體   English   中英

如何確保只調用一次函數

[英]How to make sure a function is only called once

假設我有一個名為caller的函數,它將調用一個名為callee的函數:

void caller()
{
    callee();
}  

現在可以在應用程序中多次調用調用者,並且您希望確保只調用一次調用者。 (一種懶惰的初始化),你可以使用一個標志來實現它:

void caller()
{
    static bool bFirst = true;
    if(bFirst)
    {
        callee();
        bFirst = false;
    }
}

我的意見是它需要更多的代碼,並且每次調用函數調用者都需要再檢查一次。
對我來說更好的解決方案如下:(假設被調用者返回int)

void caller()
{
    static int ret = callee();
}  

但如果callee返回void,則無法處理此情況,我的解決方案是使用逗號表達式:

void caller()
{
    static int ret = (callee(), 1);
}  

但問題在於,逗號表達式並不常用,人們在看到這行代碼時可能會感到困惑,從而導致維護問題。

你有什么好主意確保只調用一次函數嗎?

你可以用這個:

void caller()
{
    static class Once { public: Once(){callee();}} Once_;
}

線程安全:

    static boost::once_flag flag = BOOST_ONCE_INIT;
    boost::call_once([]{callee();}, flag);  

您可以通過函數指針隱藏該函數。

static void real_function()
{
  //do stuff

  function = noop_function;
}


static void noop_function()
{

}

int (*function)(void) = real_function;

呼叫者只是調用將在第一次執行工作的function ,並且不會對任何后續呼叫執行任何操作。

你用布爾標志第一個變體bFirst是什么都沒有說什么,編譯器會為你implictly在其他變體做一個顯式手動implementatuion。

換句話說,在您所提出的所有變體的典型實現中,將在生成的機器代碼中額外檢查布爾標志。 所有這些變體的性能都是相同的(如果這是您的關注)。 第一個版本中的額外代碼可能看起來不那么優雅,但這對我來說似乎並不重要。 (包裹它。)

無論如何,你所擁有的第一個變量基本上是如何正常完成的(直到你開始處理多線程等問題)

受到一些人的啟發,我認為使用宏來包裝逗號表達式也會使意圖明確:

#define CALL_ONCE(func) do {static bool dummy = (func, true);} while(0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM