2015-04-27 29 views
1

我正在開發一個程序,在C++ 11中,我需要在兩個類中使用C++ STL映射。 地圖在使用的兩個地方有相同的鍵和值列表。如何在程序中聲明/定義一次並在兩個類中使用地圖列表?

這些類是在程序的不同部分使用:

// in other part of the program 
void check_something() 
{ 
    // the size of the list can be 100, 200 or ... 
    map<string, string> amap{ 
     {"something", "nothing"}, 
     {"key", "value"}, 
    }; 

    SameClass sc{amap}; 
    // use sc 
} 

// in other part of the program 
void check_other_thing() 
{ 
    // the size of the list can be 100, 200 or ... 
    map<string, string> amap_2{ 
     {"something", "nothing"}, 
     {"key", "value"}, 
    }; 

    SameClass sx{amap_2}; 
    // use sx 
} 

現在這個工程(用於測試),但我想知道(用於維護和優化)如何聲明和定義一次然後在程序中使用我需要的地圖?

是否需要創建一個類或結構或函數,將地圖放入shared_ptr中並返回地圖?

我不想使用全局變量!

+0

如果你打算圍繞它,它只是使它成爲一個榮耀的全局變量,我推薦一個全局變量。這個圖是不變的,還是實際上是從程序的一個或多個部分修改的?這是你真正需要擔心的地方。 – chris

+3

喜歡與否,你的地圖實際上是全局變量。 – user3528438

+1

地圖不變,或者sx和sc可以改變他們自己的副本嗎? Antoher問題:僅由SameClass或不同對象使用的地圖? – Christophe

回答

1

如果你想在程序中使用WHEREVER變量,我們正在談論全局變量,你不想使用它(這很好!)。

另一種方式做,這是創建一個靜態變量,它的工作原理是全局類,但不創建名稱衝突

class Variables 
{ 
private: 
    Variables() {} // to prevent instantiation, which makes no sense 
public: 
    static map<string , int> myMap; 
    static float numba; 
}; 

float Variables::numba = 0; 
map<string , int> Variables::myMap = map<string, int>; 
//somehow initialize your static variables 

你使用這樣float var = Variables::numba


你可以也有函數返回對你的變量的引用,然後將它作爲一個指針存儲。這實際上是個好主意,因爲你不會使用任何種類的全局變量。

所以地方創建地圖,只是把它傳遞給你的對象

void setMap(map<string, string> &map) //note ampersand, it has to be a reference 
{ 
    mMap = map //where mMap means member variable in your class 
} 

如果你希望你所有的SameClass反對使用完全相同的地圖,使其靜態變量。

+0

+1我基本上同意這個想法。但是Variables :: myMap不是一個指針,所以你不要在它上面執行'new()'。 – tivn

+0

對我的壞,太多的Java:D謝謝你,我會解決這個問題。 –

0

看來您的地圖包含一種配置數據。我的理解是:

  • 您有任何地方只用一個地圖,但它包含了無處不在同一日期
  • 您的地圖是不恆定的,所以在某種程度上它應該有可能改變它(或在啓動時加載它)。

我建議你第一溶液用一個簡單的dbconfig類:

class dbconfig { 
    static map<string, string> amap; // satic: there's only one of it 
public: 
    operator const map<string,string>&() const 
    { return amap; } 
    // may be some functions to maintain the map 
}; 
map<string, string> dbconfig::amap{ // there's only one such map 
     {"something", "nothing"},  // and it's only viisble in dbconfig 
     {"key", "value"},    // so totally protected 
    }; 

的技巧是使用一個轉換操作符,只還給只讀不變。所以你可以在程序中的任何地方使用它,就像:

dbconfig cfg; // local variable. You don't have to worry about it 
SameClass sc{ cfg }; // it whill be automatically converted in a reference to 
         // your single static map. 

好處是你的配置真的封裝在一個對象中。因此,如果需要,您可以定義一些成員來管理您的地圖(添加或刪除密鑰)。由於地圖不是直接可見的,但只能通過操作員,因此可以讓dbconfig對象的內部管理髮展,而無需使用它更改代碼。例如,您可以在程序啓動時將地圖保留爲空,並在第一次請求時從配置文件或其他任何地方加載數據。

但是有一個重要的開放性問題:每個使用對象都有自己的地圖副本,還是應該參考單個地圖?

其他說明:您是否設想動態更改地圖內容,並希望所有對象都使用最新版本?

根據不同的答案,你可以定義你的用戶類別,以保持其自身的副本地圖:

class SameClass { 
    map<string, string> mine; 
public: 
    SameClass (const map<string, string>& m) : mine(m) { // const ref, but local copy 
    ... 
    }; 

或者繼續使用的引用:

class SameClass { 
    const map<string, string> & mine; // refers to the original. No own copy 
public: 
    SameClass (const map<string, string>& m) : mine(m) { // const ref ... 
    }; 
}; 
+0

我想給你的問題+1,因爲很好,但我沒有足夠的聲譽! – fm21

+0

@ fm21沒問題!感謝您的反饋 !不管你的名譽如何,如果這個答案幫助你解決你的問題,你可以接受它作爲答案。 – Christophe

1

正如許多評論人士建議,常數全局變量沒有問題。全局只有在可變時纔是問題。既然你說數據永遠不會改變,那麼簡單地把它們變成const全局變量。但是,由於它們具有複雜的構造函數,因此如果它們不是函數本地靜態,則會遇到static initialization order fiasco。因此,修復這個樣子:

文件1:

const map<string, string>& amap() { 
    static const map<string,string> v { 
     {"something", "nothing"}, 
     {"key", "value"}, 
    }; 
    return v; 
} 

文件2(或者頭)

const map<string, string>& amap(); 
0

嘗試一個星期後,我終於解決了這個!

感謝所有回答的人,我根據他們的想法解決了我的問題。

我創建了一個新的頭文件並調用它SetMap.hpp這裏是代碼:

#ifndef SETMAP_HPP 
#define SETMAP_HPP 

#include <map> 
#include <string> 

struct SetMap 
{ 
    const std::map<std::string, std::string> mymap{ 
     {"KEY_HERE","VALUE_HERE"}, 
    }; 
}; 

#endif // SETMAP_HPP 

然後我包括這頭每當我需要在我的程序和初始化結構:

#include "SetMap.hpp" 

SetMap sm; 
// use as sm.mymap; 
SameClass sx{sm.mymap}; 

SameClass的構造接受一個const地圖參考,這樣的:

SameClass (const map<string, string> &m); 

當我需要編輯鍵或值(因爲在我的程序中這個映射像一個數據庫一樣),我只需要在一個地方編輯頭文件SetMap.hpp。

這樣,就不會使用全局變量,因爲變量'mymap'在結構體的範圍內。

此處不需要類,因爲該對象很小,默認情況下該結構的變量是公共的。此外,如果需要添加同一個「概念」的其他變量 - 定義並聲明一次 - 只要您需要使用,只需將其添加到結構。

感謝所有花時間幫助我的人!

相關問題