簡體   English   中英

推遲C ++中的靜態變量構造

[英]Postpone static variable construction in C++

在我們的項目中,我們使用了外部RAM。 通常在調用構造函數時,它不會初始化或在啟動時安全使用。 因此,當需要在外部RAM中實例化一個類時,需要阻止構造函數運行,直到准備好使用外部RAM。 最好的方法是什么?

我可以想到的一種選擇是為具有正確大小和對齊方式的對象分配一些空間,然后再在此位置調​​用新的放置。

static ALTRAM union 
{
    UINT64 alignment;
    UINT8 space[sizeof(ClassName)]
}spaceHolder;
ClassName* classInstance = NULL;
...
classInstance new (&spaceHolder) ClassName();

建議的另一種選擇是將對象實例化為傳遞給實例的指針的函數中的靜態函數對象。 我在這里擔心的是,似乎該標准允許在第一次調用該函數時調用構造函數,但似乎並不需要所有編譯器都可以執行此操作。 請參閱標准中的粗體文本

static ClassName& GetInstance()
{
    static ALTRAM ClassName instance;
    return instance;
}

該項目針對Win32 VC ++和Keil for ARM進行編譯,但僅對ARM具有此要求。 是否存在編譯指示或任何其他方法來防止調用構造函數?

我正在尋找不需要修改類的解決方案。

更新

謝謝大家的答復,它非常有幫助。 我得出以下結論:

  1. 該體系結構應在應用程序運行之前初始化硬件。 這個問題在我們的團隊中引起了很多討論,並且很可能會得到解決。
  2. 一些人更喜歡新的布局方法。
  3. 對於其他方法,C ++標准要求在函數第一次執行時調用構造函數,因此這應該是可靠且可移植的解決方案。

如建議的那樣,留出一塊內存並使用new放置:

char object[sizeof(ClassName)];
new (&object) ClassName();

如果您擔心允許編譯器在需要之前構造靜態本地對象,則可以隨時添加一個間接級別:

ClassName &getInstance() {
    static ClassName *instance(NULL);
    if(!instance) instance = new ClassName;
    return *instance;
}

許多支持嵌入式系統的編譯器都帶有一些“啟動”示例代碼,這些代碼在初始化C ++環境之前執行初始化。 通常,此代碼設置ARM堆棧寄存器和其他項目。 該代碼可能是匯編語言。 您應該將內存初始化代碼放在此“啟動”代碼中。

暫無
暫無

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

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