2017-07-25 16 views
-2

我的問題更像是一種懷疑。將數據保存在.cpp和.h上的功能

幾天前,我開始組織我的代碼,但我非常喜歡它,問題是我不知道它是壞還是好,我的意思是它的工作,但我想知道如果代碼變大,最終會出現問題。這我如何用我的代碼做:

.h文件中

void init(); 
void someFunction1(); 

.cpp文件

struct myData 
{ 
    int someVar = 0; 
    int someVar1 = 21; 
} 
myData* mydata = nullptr; 

void init() 
{ 
    mydata = new myData(); 
    mydata->someVar = 1; 
} 

void someFunction1() 
{ 
    mydata->someVar = mydata->someVar1; 
} 

我知道了 「MYDATA」 指針將只是可以在這個特殊的cpp文件,並且這些函數是我包含de.h文件時唯一可以調用的函數,但這基本上是我想要的以及我正在做什麼,是否有任何問題?我的意思是,我會在將來如何使用它來獲得錯誤或任何奇怪的東西?

+1

_「我知道了‘MYDATA’指針將只是可以在這個特別的cpp文件「,_不,這是錯誤的。如果你在那裏放置一個「靜態」,那將是真的。另外,在C++中,使用具有私有數據和公共成員函數的類。 – user0042

+0

是的,這將是一個問題。不要創建返回void且不帶參數的函數,也不要在文件範圍創建變量。 –

+1

請不要在C++問題上使用C標籤,它們是不一樣的。 –

回答

1

mydata也可用於其他翻譯單位。如果在另一個源中使用另一個使用相同名稱的全局變量,這可能會造成問題。這將導致標識符衝突。

要確保不會發生這種情況,你可以做mydata一個靜態變量:

static myData* mydata = nullptr; 

或把mydata在具名命名空間:

namespace { 
    myData* mydata = nullptr; 
} 

在這種情況下,myData做不一定是靜態的。

現在,第二種選擇通常在C++中首選,但第一種選擇將實現相同的結果,並且沒有任何內在錯誤。

請注意,全局範圍的變量有一些與它們相關的問題,與初始化有關。例如,如果將全局變量初始化爲另一個其他全局變量的值,則無法知道哪個變量會首先被初始化,因此您的變量可能會使用垃圾數據進行初始化。然而,在這種情況下,你只是將它初始化爲nullptr,所以沒關係。但是,避免使用全局變量是一個很好的習慣,因爲有更好的方法來做到這一點。你可以用該變量爲靜態函數來代替,返回其內定義一個靜態變量:

static myData& mydata() 
{ 
    static myData mydata_instance; 
    return mydata_instance; 
} 

void init() 
{ 
    mydata().someVar = 1; 
} 

void someFunction1() 
{ 
    mydata().someVar = mydata().someVar1; 
} 

另外請注意,沒有指針使用。 mydata_instance是一個對象,而不是指針,這就避免了必須使用new來分配內存,這意味着您不必擔心調用delete以後再釋放內存。 mydata()將在第一次調用時在堆棧上創建一個myData對象,並且由於該對象是靜態的,因此將在每次將來每次調用mydata()時保留,並且每次都會返回同一對象(靜態局部變量僅初始化一次)。請注意,返回類型mydata()是一個引用(用&表示),這意味着當您返回對象時,將返回該對象的引用而不是副本。這使您可以直接訪問函數外部的mydata_instance對象。

現在,儘管上述方法可行,但擺脫init()函數並重新設計myData結構可能不是一個好主意。在這種情況下,只需在結構本身中將someVar成員設置爲1即可。沒有理由將其初始化爲0的結構裏面隨後必須將其稱之爲init()將其設置爲1,所以,總體來說:

struct myData 
{ 
    int someVar = 1; 
    int someVar1 = 21; 
} 

static myData& mydata() 
{ 
    static myData mydata_instance; 
    return mydata_instance; 
} 

void someFunction1() 
{ 
    mydata().someVar = mydata().someVar1; 
} 
+0

非常感謝您的解釋。哦,關於初始化方法,這只是一個例子,我通常不會那樣做,只是表達我在說什麼,但是再次,謝謝 – khofez

1

我知道了「MYDATA」指針將只是可以在這個特定的CPP文件

那是假的。 mydata將是一個全局變量。如果另一個.cpp中有另一個mydata全局變量,它們可能會發生衝突(或者至少它們會違反一個定義規則)。對於MYDATA

使用未命名空間:

namespace { 
    myData* mydata = nullptr; 
} 

這樣,mydata不會對其他翻譯單元進行訪問。

但是:不推薦使用全局變量。不要使用它們。他們幾乎總是有替代品。

還有一個技術原因,這++只涉及到C:static initialization order fiasco

而且有設計決策背後:

+0

爲什麼不推薦全球變量?你能舉一個簡單的例子嗎? – khofez

+0

謝謝你的回答! – khofez