2012-02-21 4 views
5

मैं किसी पाठ फ़ाइल में एक वर्ग के एक समारोह है कि यह करने के लिए भेजा डेटा बचाता है कि बनाने के लिए, चाहते हैं। डेटा इसे करने के लिए पारित किया जा सकता है कि एक std::string, int, double, float, unsigned int, आदि जैसे कुछ भी हो सकता है, और यह भी एक हो सकता है: std::vector<T>, T[], और std::vector<std::vector<T>>, T[][]सी ++ सरणियों, वैक्टर, प्रकार में बनाया के लिए टेम्पलेट समारोह, एसटीएल

अब, जाहिर है, अगर यह एक सरणी है, मैं इसे माध्यम से पुनरावृति करने के लिए पाठ-फाइल करने के लिए डेटा भेजने के लिए की आवश्यकता होगी।

मैं टेम्पलेट का उपयोग कर के बारे में सोच रहा था, लेकिन मैं सरणियों कैसे करना है यकीन नहीं है।

क्या यह जाने का रास्ता है?

class CMyClass 
{ 
    template<typename T> 
    void SaveData(T data); 
    void SaveData(std::vector<T> data); 
    void SaveData(std::string data); 
    void SaveData(T* data);    // Perhaps I'll also need to pass in the size. 
    void SaveData(std::vector<std::vector<T>> data); 
    void SaveData(T** data); 
}; 

मैं कल्पना है कि std::string के लिए कोड std::vector<T> के लिए प्रदान की है कि T एक प्रकार में बनाया गया (एक int या float या कुछ और की तरह) है कोड के रूप में ही किया जाएगा।

और फिर मैं SaveData(...) तदनुसार से प्रत्येक के लिए काम करता है लिखना?

+0

आपका शीर्षक बहुत व्यापक और अस्पष्ट है, आप इसे फिर से बदलना चाहेंगे। –

+4

एफवाईआई: http://www.boost.org/doc/libs/1_48_0/libs/serialization/doc/index.html – Anycorn

उत्तर

5

सबसे पहले, आप वर्ग या कार्यों टेम्पलेट कर सकते हैं या तो। चूंकि आप एरे भी करना चाहते हैं, इसलिए आप को बाद वाले विकल्प के साथ जाना चाहिए।उदाहरण इस प्रकार है:

class CMyClass 
{ 
public: 
    template<typename T> void SaveData(const T &data); 
    template<typename T, size_t N> void SaveData(const T (&data)[N]); 
    template<typename T, size_t N, size_t M> void SaveData(const T (&data)[N][M]); 
    template<typename T> void SaveData(const std::vector<T> &data); 
    template<typename T> void SaveData(const std::vector<std::vector<T> > &data); 
    void SaveData(const std::string &data); 
}; 

एक बार जब आप कार्यों को परिभाषित किया है, तो निम्न उदाहरण दिखाता है कि आप उन्हें फोन कर सकते हैं:

int i; 
int i1[5]; 
int i2[5][7]; 
std::vector<int> v1; 
std::vector<std::vector<int> > v2; 
std::string s; 

CMyClass saveClass; 

saveClass.SaveData<int>(i); 
saveClass.SaveData<int>(i1); 
saveClass.SaveData<int>(i2); 
saveClass.SaveData<int>(v1); 
saveClass.SaveData<int>(v2); 
saveClass.SaveData(s); 

अपनी आवश्यकताओं के आधार पर, आप कक्षा एक सिंगलटन कर सकता है और कार्यों स्थिर , सभी एक ही CMyClass का दृष्टांत की जरूरत को छोड़ते हुए और कार्यों बस बुला इस प्रकार है:

CMyClass::SaveData<int>(i); 
CMyClass::SaveData<int>(i1); 
CMyClass::SaveData<int>(i2); 
CMyClass::SaveData<int>(v1); 
CMyClass::SaveData<int>(v2); 
CMyClass::SaveData(s); 

नोट्स:

  1. तर्क भी संदर्भ होना चाहिए (यानी। "&" डेटा "के बजाय डेटा"), ताकि जब भी आप फ़ंक्शन को कॉल करते हैं तो पूरे कंटेनर की एक प्रति करने के बजाए केवल संदर्भ पारित किया जाता है।
  2. मैंने स्पष्ट रूप से कार्यों को जनता के रूप में घोषित कर दिया है, मानते हुए कि यह पूरी कक्षा है और इसके कार्यों को किसी अन्य वर्ग द्वारा एक्सेस किया जाएगा। डिफ़ॉल्ट रूप से, कक्षा के सदस्य निजी होते हैं।
  3. सुनिश्चित करें कि प्रत्येक नेस्टेड ">" के बीच एक जगह है।

शुभकामनाएँ!

+0

आपको बहुत धन्यवाद! वह वास्तव में मदद करता है। मेरे पास एक सवाल है, फिर भी आपने डेटा के बजाय शब्द सरणी का उपयोग क्यों किया? क्या यह सिर्फ एक नामकरण चीज है, या ... क्या यह कुछ करता है, क्योंकि मैंने पढ़ा है कि केवल वीएस में यह कुछ करता है। –

+0

परिवर्तनीय नाम के रूप में "सरणी" का मेरा उपयोग आदत का एक बल था। मैंने कोड संपादित किया है ताकि इंटरफेस स्थिरता बनाए रखने के लिए अब यह "डेटा" हो। चिंता न करें, "सरणी" सी ++ में कोई कीवर्ड नहीं है। किसी भी भ्रम के लिए खेद है जो हो सकता है! – athwaites

+0

धन्यवाद, एक अंतिम प्रश्न, std :: vector > को लागू करने के लिए, मुझे फिर से एक अलग ओवरलोड करना होगा, मैं इस तथ्य के बावजूद कि विधि संभवतः std :: वेक्टर >? –

0

मेरा मानना ​​है कि आप एक वर्ग है, जो बचा जाना चाहिए में दो बातें मिश्रण कर रहे हैं: जहाँ तक मैं देख सकता हूँ, क्या अपने वर्ग के बारे में है (अपने "जिम्मेदारी") एक फाइल करने के लिए डेटा लिखने के लिए है। एक और चीज जो आप जोड़ रहे हैं वह आंकड़ों के संग्रह को पुन: स्थापित करने के बारे में जानकारी है।

एसटीएल के <algorithm> तरीकों पर एक नज़र डालें:

http://www.cplusplus.com/reference/algorithm/

वहाँ आप बार-बार दोहराना डेटा, जैसे की सामान्य तरीके ढूँढ सकते हैं find विधि में:

template<class InputIterator, class T> 
    InputIterator find (InputIterator first, InputIterator last, const T& value) 
    { 
    for (;first!=last; first++) if (*first==value) break; 
    return first; 
    } 

यह आपको आप vector, list, सरणियों या जो कुछ भी उपयोग कर रहे हैं कि क्या से स्वतंत्र बना देता है।

यदि आप vector<vector<T> > जैसी चीजों को क्रमबद्ध करना चाहते हैं (दो > के बीच की जगह को नोट करें!), तो आपको इस डेटा के साथ क्या करना है, इस पर अधिक व्याख्या करना होगा। बस तत्वों को संकलित करें जैसे कि सभी T एस vector में थे? इस मामले में आप एक नया इटरेटर बनाने की कोशिश कर सकते हैं जो वास्तव में ऐसा करता है।

बढ़ावा इटरेटर पुस्तकालय इस के साथ मदद कर सकता है:

http://www.boost.org/doc/libs/1_48_0/libs/iterator/doc/index.html

+0

सुझाव के लिए धन्यवाद। विस्तृत करने के लिए, मैं इस फैशन में एक टेक्स्ट फ़ाइल में जो कुछ भी पास कर चुका हूं उसे लिखना चाहता हूं: ifstream ifs ("test.txt", ifstream :: in); ifs << डेटा। यदि डेटा एक वेक्टर है, तो डेटा को एक int है, तो मुझे इसे फिर से चालू करना होगा, तो मैं नहीं करता। यदि डेटा एक टी [] [] है तो मुझे उस पर भी पुन: प्रयास करना होगा ... मुझे std :: एल्गोरिदम और कार्यों के बारे में पता है जैसे for_each (...); हालांकि, मैं नहीं देखता कि अगर उपयोगकर्ता int या char में गुजरता है तो वे कैसे मदद करेंगे। साथ ही, मुझे विश्वास नहीं है कि मैं std :: vector > जैसी चीज़ों के लिए std :: for_each का उपयोग कर सकता हूं। –

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