2014-01-30 84 views
0

雖然我正在開發我的程序,但我試圖訪問和創建對象時遇到了問題,我正在慢慢學習C++。我的目標是一個名爲source.cpp頁面上創建與來自另一個類的訪問對象C++

Tilemap background; 

我還有一個頭文件,它在燕鷗要求與需要訪問「背景」的功能,該文件被稱爲「player.cpp」,但我無法弄清楚如何定義它。我包含了帶有tilemap類的頭文件,但由於該對象是在別處創建的,我不知道如何引用它。谷歌今天不是我的朋友,我的搜索沒有提到任何東西。

+2

代碼將有助於表達這裏的問題。伴隨着精確的編譯器錯誤。player.cpp中的 –

+0

使用'extern Tilemap background;' –

回答

3

Tilemap background; 

在文件範圍書面(即,不是一個功能塊內)是一個全局變量定義。它爲全局數據分配一個稱爲背景的變量。

如果要從其他C++源文件中引用此對象,首先需要聲明該變量,以便編譯器知道它的類型。

// In another .cpp file 
extern Tilemap background; 

void f() 
{ 
    background.something(); 
} 
+0

那麼簡單嗎?你已經爲我節省了很多頭部劃痕,這很有意義,但我已經嘗試了所有工作幾個小時,因爲這個簡單的答案,我可以大大提高部分代碼的質量。非常感謝你。 – Mystic

1
Tilemap background; 

放置在全球範圍內(讓我們的地方說你source.cpp文件的開頭)宣佈可能只在source.cpp一個全局變量,只有在默認情況下,同一個編譯單元是可訪問的(在這種情況下, )。在player.cpp中,編譯器不知道存在變量background

一種解決方案可能是把:

extern Tilemap background; 

player.cpp讓編譯器知道有定義別的地方Tilemap類型的全局變量。

不過,我覺得更好的主意,避免使用這種的全局變量和嘗試的論點形式以「傳播」(通)變量/對象,而調用一些成員函數(「辦法」)。畢竟,對象之間的通信是面向對象編程的內容......(我會提供一些具體的例子,如果我知道這個類的上下文/如果你分享了一些代碼......)

0

好,所以你正在學習C++然後從一開始就學習好的實踐並避免C++陷阱。以這種方式聲明和使用C++全局對象可能會導致非常討厭的行爲和長時間的調試會話,因爲您無法確定在文件全局作用域中聲明的全局對象背景是否已在其他文件中使用時被初始化並正確構造。當你使用這樣一個對象時,讓我們把它稱爲B,在另一個文件中的另一個全局對象A中,你不能確定B在A之前被初始化,並且導致非常討厭的錯誤,或者如果你幸運的是崩潰。然後解決方案:讓你將本地背景靜態對象當作本地靜態對象,例如:

TileMap& getBackground() { 
    static TileMap background; //use of "camel case" for the class name 
    return background; //return a reference to it 
} 

就是這樣。任何你想使用背景的地方都可以調用getBackground()。第一次調用它時,背景本地靜態將被初始化並且很好用。

有人會說這種技術與單件設計模式有關,但這不是我的意圖,如果您絕對需要,它只是使用全局對象的正確方法。特別是C++ 11的發佈,C++是一門很棒的語言,但它有一些需要注意的缺陷。幫你一個忙:拿一份Effetive C++它會教你幾乎所有你需要知道的使用正確的語言

+0

這種惰性初始化有時是有用的,它確實避免了靜態對象構造的一些問題,但它也有它自己的問題,特別是如果你的程序是多線程的 - 它不是線程安全的。 –

+0

仍然您提供的解決方案導致未定義的行爲,不建議。線程安全性是另一個問題,這兩種解決方案都不適用於這個問題。按照你說的方式繼續使用全局變量是錯誤的。僅僅因爲C++允許你這樣做,你不應該在自己的腳中開槍。 – Imaxd