2012-06-05 19 views
13

मेरा लक्ष्य एक सी ++ गेम में वैश्विक स्थिरांक होना है जो मैं काम कर रहा हूं (कुछ ग्राफिक्स जानकारी और इसी तरह का प्रतिनिधित्व करने के लिए)। मेरा वर्तमान कार्यान्वयन उन सभी को एक .h में टॉस करना और उन्हें हर जगह शामिल करना है। यह काम करता है, सिवाय इसके कि हर बार जब मैं एक सेटिंग बदलता हूं, तो संपूर्ण कोड बेस को फिर से सम्मिलित किया जाना चाहिए।वैश्विक विन्यास का उचित कार्यान्वयन

तो, मेरा अगला विचार उन्हें कुछ कॉन्फ़िगरेशन txt फ़ाइल में टॉस करना था और उन्हें पार्स करना था, इस तरह सेटिंग्स बदलते समय वास्तव में कोई कोड नहीं बदला जाता था। पार्सर काफी सरल था, और मैं मूल्यों को स्थिरांक में डाल सकता था, लेकिन क्योंकि पार्सर कोड ब्लॉक था, स्थिरांक अब वैश्विक नहीं थे।

क्या इसे हल करने का कोई अच्छा तरीका है? शायद ब्लॉक में होने के बावजूद उन्हें ग्लोबल बनाने का कोई तरीका या सेटिंग्स बदलने के दौरान सब कुछ पुनः संयोजित करने से बचने के लिए?

उत्तर

11

ऐसा करने का एक और तरीका एक सिंगलटन वर्ग बनाना होगा।

#include <fstream> 
#include <map> 
#include <string> 

class ConfigStore 
{ 
public: 
    static ConfigStore& get() 
    { 
     static ConfigStore instance; 
     return instance; 
    } 
    void parseFile(std::ifstream& inStream); 
    template<typename _T> 
    _T getValue(std::string key); 
private: 
    ConfigStore(){}; 
    ConfigStore(const ConfigStore&); 
    ConfigStore& operator=(const ConfigStore&); 
    std::map<std::string,std::string> storedConfig; 
}; 

यहाँ विन्यास मानचित्र में सहेजा जाता है, जब तक कि parseFile फ़ाइल पढ़ सकते हैं और getValue प्रकार अगर आप नए कुंजियों को जोड़ने config वर्ग पुन: संयोजित करने के लिए कोई जरूरत नहीं है पार्स कर सकते हैं जिसका अर्थ है।

उपयोग: क्योंकि यह मुझे एक कॉन्फ़िग फ़ाइल में लोड है, तो कोई उपयोगकर्ता किसी भी संकलन के बिना सेटिंग में बदलाव कर सकता है की सुविधा देता है

std::ifstream input("somefile.txt"); 
ConfigStore::get().parseFile(input); 
std::cout<<ConfigStore::get().getValue<std::string>(std::string("thing"))<<std::endl; 
+0

माना जाता है कि मैं मूल रूप से इसे इस तरह के अतिरिक्त संरचनाओं के बिना करना चाहता था, लेकिन यह अधिक ओओ सम्मेलनों का पालन करता है और सामान्य रूप से बेहतर काम कर रहा है! मुझे जोआचिम के सुझाव भी पसंद आया, लेकिन यह मेरे लिए हल किया गया है, धन्यवाद! – akroy

+1

@akroy मैं असहमत होना चाहता हूँ। आप किस प्रकार के ओओ सम्मेलन का यहां भी मतलब रखते हैं? हमारे पास एक सिंगलटन है। कुछ प्रोग्रामर दोस्त का समाधान एक सिंगलटन को शुरू करने के लिए स्पष्ट रूप से बेहतर लगता है जो मूल रूप से धीमी लुकअप के साथ 'std :: map' के आस-पास बनाया गया है और बिना किसी प्रकार की सुरक्षा के नंगे चर के साथ – IceFire

+0

अरे IceFire! संदर्भ के लिए, यह प्रश्न 5 साल पहले से था जब मैं पहली बार प्रोग्राम सीखना था। टिप्पणी थ्रेड को देखते हुए, ऐसा लगता है कि मैंने सिद्धांत में कुछ प्रोग्रामर दोस्त का समाधान भी पसंद किया है, लेकिन इसे कंपाइलर से पहले नहीं मिला। तो, अगर यह आपके लिए संकलित करता है, तो आपके लिए अधिक शक्ति। :) – akroy

1

केवल मुख्य फ़ाइल में घोषणाएं डालें और परिभाषाओं को एक सीपीपी फ़ाइल में रखें। तो आप सीपीपी फ़ाइल में परिभाषाओं को बदल देंगे, सभी कोड को पुन: संकलित नहीं किया जाएगा

2

आपके कॉन्सेंट्स को वापस करने वाले कार्यों को बनाने के बारे में क्या है जो आप एक .cxx फ़ाइल में निर्दिष्ट कर सकते हैं? उदाहरण के लिए:

// foo.h 
const int BAR(); 

// foo.cxx 
const int BAR() { 
    return 10; 
}; 
17

तरह से मैं का समाधान इस एक अलग वैश्विक नामस्थान, जो config.h की तरह कुछ नाम के एक हेडर फाइल में है में चर डालने के लिए प्रयोग किया जाता है, तो हर जगह है कि फाइल में शामिल हैं।

// In config.h 

#ifndef CONFIG_H 
#define CONFIG_H 

namespace config 
{ 
    extern int some_config_int; 
    extern std::string some_config_string; 

    bool load_config_file(); 
} 

#endif 

एक स्रोत फ़ाइल में The, आप परिभाषित चर और यह भी उन्हें एक डिफ़ॉल्ट मान पर सेट। इस स्रोत फ़ाइल में आपके कॉन्फ़िगरेशन फ़ाइल से चर लोड करने के लिए कोड भी है।

// In config.cpp 

namespace config 
{ 
    int some_config_int = 123; 
    std::string some_config_string = "foo"; 
} 

bool config::load_config_file() 
{ 
    // Code to load and set the configuration variables 
} 

अब हर स्रोत फ़ाइल में आप, विन्यास चर जरूरत config.h शामिल हैं और उन्हें config::some_config_int तरह का उपयोग।

हालांकि, इसे हल करने का कोई "उचित" तरीका नहीं है, मेरी आंखों में काम करने के सभी तरीके उचित हैं।

+0

यह समाधान, वास्तव में आदर्श लग रहा है। लेकिन, मैंने आपके द्वारा उपयोग किए गए कोड तर्क का बिल्कुल अनुकरण करने की कोशिश की, और मुझे हर बार किसी भी चर का उपयोग करने के लिए "कॉन्फ़िगर :: VARIABLE_NAME '' अपरिभाषित संदर्भ मिल रहा है। यहां तक ​​कि जब भी मैंने किसी भी लोड फ़ंक्शन का उपयोग नहीं किया और पूरी तरह से परिभाषित किया .cpp में चर, मुझे एक ही त्रुटि मिली। (मैंने सटीक उसी वाक्यविन्यास का उपयोग किया था जैसे आप बाहरी में .h और .cpp में पूर्ण घोषणा और परिभाषा) – akroy

+0

@Akroy आप नई स्रोत फ़ाइल के साथ निर्माण/लिंक करते हैं? –

+0

मैंने किया। इसलिए, अगर config.h में नेमस्पेस कॉन्फ़िगरेशन {बाहरी int x;} है, config.cpp में नेमस्पेस कॉन्फ़िगरेशन {int x = 5;} है, फिर दूसरी फ़ाइल में जिसमें #include "config.h" है, मुझे चाहिए config :: x तक पहुंचने में सक्षम हो? क्या मुझे कुछ याद आ रही है? – akroy

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^