程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> c++-C++私有內部類靜態變量未進行類體外定義

c++-C++私有內部類靜態變量未進行類體外定義

編輯:編程綜合問答
C++私有內部類靜態變量未進行類體外定義

以下為Singleton.h:

class HungerSingleton
{
private:

    class CGarbo  // 用於析構s_pInstance
    {
    public:
            ~CGarbo()
        {
            if(HungerSingleton::s_pInstance)
                delete HungerSingleton::s_pInstance;
        }
    };
    static CGarbo Garbo;
    static HungerSingleton *s_pInstance;
public:
    static HungerSingleton * GetInstance()
    {
        return s_pInstance;
    }
};

下為Singleton.cpp:
HungerSingleton* HungerSingleton::s_pInstance = new HungerSingleton;

測試函數:
void TestSingleton()
{
HungerSingleton *phgl = HungerSingleton::GetInstance();
}


為什麼Garbo作為靜態變量沒有在類外部定義,而程序卻沒有報錯呢?

最佳回答:


測試環境:VS2013的優化已禁用 (/Od),警告等級 4 (/W4)

因為你的 static CGarbo Garbo;的 CGarbo類裡面並沒有數據成員,CGarbo是一個空類,所以sizeof(CGarbo)==1; 如果CGarbo的public(為了測試方便)加上一個數據成員char c,另外在HungerSingleton類的GetInstance()加上cout << Garbo.c << "\n"; 那麼sizeof(CGarbo)還是==1; 但是在我加上char c以後,你的CGarbo有了數據成員,此時執行我給你的新改裝類,則會滿滿的報錯,error LINK2001(不解釋),因為對於無數據成員的類,編譯器會產生於有數據成員的類不同的目標代碼,所以加上char c以後,類的目標碼不同,而且編譯器知道你用了未初始化的Garbo.c,如果你不在外部顯示提供初始化,是通不過的。但是你去掉cout << Garbo.c << "\n";這句,可以通過,因為編譯器在編譯的時候發現你自始至終沒用過Garbo的.c,故不影響鏈接,不會報錯。

另外補充一句,現在的編譯器很智能,即使在10年前,Silicon Graphics的N32和N64編譯器已經能自動為所有型別提供適當的type_traits的特化版本,進行STL優化。10年過去了,編譯器技術突飛猛進,如果你懂匯編,去調整編譯器的優化級別,反復觀察匯編碼,你就知道編譯器給你優化了什麼了。(我用的的/Od)

最有給你我改的代碼,注釋部分你好好看看,如果你去掉cout << Garbo.c << "\n";的注釋,就會報錯。此時你再去掉首位的注釋去初始化,問題就OK了。

#include
using std::cout;

class HungerSingleton
{
private:

class CGarbo  // 用於析構s_pInstance
{
public:
    //CGarbo(char c) :c(c){ }
    char c;
    ~CGarbo()
    {
        if (HungerSingleton::s_pInstance)
            delete HungerSingleton::s_pInstance;
    }
};
static CGarbo Garbo;
static HungerSingleton *s_pInstance;

public:
static HungerSingleton* GetInstance()
{
//cout << Garbo.c << "\n";
cout << sizeof(CGarbo) << "\n";
return s_pInstance;
}
};
HungerSingleton* HungerSingleton::s_pInstance = new HungerSingleton;
//HungerSingleton::CGarbo HungerSingleton::Garbo('a');

void TestSingleton()
{
HungerSingleton *phgl = HungerSingleton::GetInstance();
}

int main()
{
TestSingleton();

return 0;

}

你的問題非常好,我學習了。祝你事業進步,生活快樂!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved