2012-01-10 49 views
0

如果我使用的是單件模式(是的,我知道 - 他們通常是不好的)......我有一個實例函數,像這樣:什麼存儲類是一個函數內部的靜態,爲什麼?

MySingleton* Instance() { 
    static MySingleton instance; 
    return &instance; 
} 

哪些存儲類是instance

我在讀「程序由David R. Butenhof POSIX線程」,和我遇到的文本說出來:

大多數時候,你會使用extern或static聲明可能條件變量存儲類在文件範圍內,即在任何函數之外。如果它們被其他文件使用,它們應該具有普通(extern)存儲類;如果僅在聲明該變量的文件中使用它們,它們應該具有靜態存儲類。

由於這個靜態函數是一個函數,它是自動的嗎?或者是因爲靜態關鍵字而不同的類?

如果我將「實例」變量移動到其文件中的靜態和全局(不在任何函數中) - 我仍然可以將其引用到另一個文件,或者不起作用嗎?

回答

4

我認爲作者已經合併了存儲時間和鏈接,但建議使用什麼關鍵字是正確的。

您的函數範圍變量instance具有靜態存儲持續時間。如果沒有static關鍵字,它會自動存儲持續時間。

文件範圍爲的對象始終爲具有靜態存儲持續時間(或C++ 11中的關鍵字thread_local)的靜態存儲持續時間。在文件範圍使用static關鍵字給出對象內部鏈接,extern給它外部鏈接,它們不影響存儲持續時間。

由於static是一個所謂的「存儲類說明符」,所以描述某些具有「靜態存儲類」是正確的,但它不是全部故事,因爲文件範圍中的static的含義與函數中的含義不同範圍。

您可以將具有靜態存儲持續時間的對象的引用傳遞給其他翻譯單元的代碼。它是否具有文件範圍或功能範圍並不重要,並且它的連接是什麼並不重要。 「如果其他文件使用它們,它們應該具有普通(extern)存儲類」,這意味着如果其他文件將引用的名稱,則表示全局需要外部鏈接,因爲具有內部鏈接的全局名稱是指每個TU中的不同對象。從技術上講,這是有聯繫的名稱,而不是對象。

+0

感謝您的答案 - 您擊中了發現讓我困惑的東西:)你知道一個很好的資源來學習這些東西嗎?在我的任何一本C++書籍中,我都沒有遇到過(以任何重要的方式) - 只是一些奇怪的參考資料,這些參考資料並不足以從中學習。 – 2012-01-10 14:43:04

+0

@ w00te:標準。閱讀「存儲時間」,「連接」和「存儲類別說明符」的完整章節。然後重新閱讀關於鏈接的部分,因爲雖然鏈接本身非常簡單,但是具有不同存儲類別說明符的多個聲明的規則混淆了我。於是最後,它可能是值得一讀的東西實現特定如何DLL導入/導出是由編譯器來處理,因爲雖然它是不一樣的聯動是非常密切的關係。 – 2012-01-10 14:46:47

+0

謝謝,我會添加到我的閱讀列表 - 雖然它聽起來像它可能把我胎位:) – 2012-01-10 17:48:29

4

instance有一個靜態存儲類,因爲它具有static限定符沒有它的限定它將是automatic變量與本地範圍。
在文件範圍聲明的靜態變量具有內部鏈接,您不能在不同的文件中使用它們。
如果你想聲明一個可以跨文件使用的全局變量,那麼你需要使用extern,它給出了可變的外部鏈接。

+0

因此,例如(在單實例)可以跨文件使用,但如果我在文件範圍內聲明它,我不能跨文件使用它呢? – 2012-01-10 14:36:42

+0

@ w00te:第一個靜態的內部功能範圍僅限於該功能,而在一個文件中的靜態已範圍僅限於該文件。 – 2012-01-10 14:38:16

+0

那麼,這是否單身方法不行,還是可以的,因爲指針返回到存儲位置,我們很肯定,位置仍然存在,因爲它的靜態? – 2012-01-10 14:39:26

1

一般Singleton模式在項目中使用,這樣會有一個只在該項目中使用的實例。像數據庫連接池生成器或配置。辛格爾頓在使用方式如下:將始終調用必須是靜態的和私人的類的實例,在類的構造函數必須是私有的,中的getInstance函數必須是公開的。 讓我們來看看下面:

/** 
* @author harzumanian 
* 
*/ 
public class LogManager { 

    private File file = null; 
    private static LogManager logger = null; 

    /** 
    * 
    */ 
    private LogManager() { 
     file = new File(Constants.PLUGIN_LOG); 
    } 

    public static LogManager getLogger() { 
     if (logger == null) { 
      logger = new LogManager(); 
     } 
     return logger; 
    } 
} 
相關問題