2016-04-07 63 views
1

的功能,這是我的類定義:調用靜態成員

#ifndef CloudFunctions_hpp 
#define CloudFunctions_hpp 

#include "WebRequest.hpp" 
#include "external/json/document.h" 
#include <stdio.h> 

typedef std::function<void(const rapidjson::Document&)> CloudCallback; 

class CloudFunctions 
{ 
private: 
public: 
    static WebRequest request; 
    static void GetData(const CloudCallback &callback); 
}; 

#endif /* CloudFunctions_hpp */ 

基本上從REST API這個類下載數據並調用回調參數的功能。

這是的GetData功能:

void CloudFunctions::GetData(const CloudCallback &callback) 
{ 
    CloudFunctions::request.get("decks", [&](const std::string &result){ 
     CCLOG("Loaded"); 
    }); 
} 

不幸的是,這並不編譯:

Undefined symbols for architecture x86_64: 
    "CloudFunctions::request", referenced from: 
     CloudFunctions::GetData(std::__1::function<void (rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator> const&)> const&) in CloudFunctions.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

如果我把要求成員和的GetData功能分爲非靜態,然後代碼編譯。

這是怎麼回事?

+0

你有沒有申報你的靜態變量的定義?例如'WebReqeust CloudFunctions :: request;' – foo

+0

我應該在哪裏聲明它?你的意思是在課外? –

+0

是你的cpp – foo

回答

3

您需要定義靜態成員變量request。你所做的只是爲它提供一個聲明。又見Undefined reference to static variable c++

例如:

class A 
{ 
public: 
    static int var; 
}; 

在你的CPP可以初始化它,然後:

int A::var = 0; 

然後你可以使用它像這樣:

int main() 
{ 
    A::var = 5; 
} 
1

因爲request是靜態數據成員,所以您必須在全局範圍內,在類聲明之外對其進行初始化。靜態數據成員不會被任何構造函數初始化(因爲它們不屬於任何實例),所以在類聲明中,您只是聲明靜態數據成員,而不是初始化它(或者實例化它或任何其他術語喜歡)。你需要一個靜態上下文來初始化靜態數據,所以這就是你在全局範圍內執行它的原因。即使該成員是私人的,你也可以這樣做。

因此,任何類外,你只需要輸入WebRequest CloudFunctions::request;

1

你實現CC文件應包含以下行:

WebRequest CloudFunctions::request; // include constructor arguments here 

小心不要碰到靜態初始化順序的悲劇。如果其他實現文件具有依賴於CloudFunctions::request的靜態初始化,那麼它們可能最終在初始化/構建之前使用它。

請考慮使用單例代替。

+0

感謝您的建議。我來自C#,而且我正處於被C++所提供的一切困惑的階段:-) –

+0

直到最後一句話爲止的最佳答案:_「請考慮使用單例。」_沒有爲你付出代價。 –

+0

謹慎闡述?我提出了一種解決靜態初始化順序問題的方法。 – LLFF