2012-06-04 23 views
6

में स्थिर काउंटर मैं Data कक्षा बनाने की कोशिश कर रहा हूं जिनकी वस्तुओं में प्रत्येक अद्वितीय आईडी है।सी ++

मैं 1 वस्तु की आईडी 1 होना चाहता हूँ, 2, 2 होने के लिए आदि मैं एक static int, लेकिन सभी वस्तुओं एक ही आईडी है का उपयोग करना चाहिए, नहीं 1, 2, 3 ...

यह Data वर्ग है:

class Data 
{ 
private: 
    static int ID; 
public: 
    Data(){ 
    ID++; 
    } 
}; 

मैं ऐसा कैसे यह इतना पहले एक आईडी 1 होगा कर सकते हैं, दूसरा होगा 2, आदि ..?

+0

सुनिश्चित करें कि आप टी मल्टीथ्रेडिंग की एके देखभाल, क्योंकि चर 'स्थिर' है। – iammilind

+0

आम तौर पर लोग 'int' के बजाय इसके लिए' long' का उपयोग करते हैं। – shan

+0

@shan: कौन से लोग? वह चाहे जो भी हो वह हो सकता है। –

उत्तर

9

यदि आईडी स्थिर है, तो यह सभी वर्ग के उदाहरणों के लिए समान मूल्य होगा।

आप प्रत्येक उदाहरण चाहते हैं अनुक्रमिक आईडी मान होना है, तो आप स्थिर विशेषता एक वर्ग चर के साथ, इस तरह जोड़ सकता:

class Data 
{ 
private: 
    static int ID; 
    int thisId; 
public: 
    Data(){ 
    thisId = ++ID; 
    } 
}; 

int Data::ID = 0; 

आवेदन बहु लड़ी हो जाएगा, तो आप होगा इसे एक pthread mutex की तरह कुछ के साथ सिंक्रनाइज़ करने के लिए।

+0

धन्यवाद, इस समाधान के बारे में सोचा लेकिन मैं सोच रहा था कि ऐसा करने का दूसरा तरीका है, केवल स्थिर int के साथ, क्योंकि मुझे केवल स्थिर int का उपयोग करके ऐसा करने का अनुरोध किया गया था। धन्यवाद! :) – Jjang

+0

@Jjang, यदि आप केवल कन्स्ट्रक्टर में मान प्रिंट करते हैं, तो आप इसे केवल एक स्थिर int के साथ कर सकते हैं, लेकिन यदि आपको *** *** अद्वितीय अनुक्रमिक मान *** स्टोर करने की आवश्यकता है, तो आपको बस से अधिक की आवश्यकता होगी स्थैतिक int। – Brady

+0

@Jjang: आपके पास एक * साझा * आईडी ('स्थिर ') के साथ * अद्वितीय * आईडी प्रति ऑब्जेक्ट नहीं हो सकता है, जो बिल्कुल समझ में नहीं आता है। –

14

यह:

class Data 
{ 
private: 
    static int ID; 
    const int currentID; 
public: 
    Data() : currentID(ID++){ 
    } 
}; 

एक स्थिर काउंटर के अलावा, आप भी एक उदाहरण के लिए बाध्य सदस्य की जरूरत है।

+3

सदस्य आईडी एक 'const' फ़ील्ड होना चाहिए। एक बार वस्तु बनने के बाद यह संभवतः इसे बदलने के लिए कोई समझ नहीं आता है। यह ऑब्जेक्ट की आईडी को ओवरराइट करने से 'ऑपरेटर =' को स्वचालित रूप से अवरुद्ध कर देगा, भले ही उपयोगकर्ता को एक कॉपी कन्स्ट्रक्टर प्रदान करने की ज़िम्मेदारी के साथ छोड़ा गया हो जो स्रोत ऑब्जेक्ट की आईडी का पुन: उपयोग नहीं करता है। –

+0

@ डेविडरोद्रिगुएज़-ड्राईबेस अच्छा बिंदु। –

+0

मैंने अपने उपयोगकर्ता द्वारा घोषित प्रतिलिपि निर्माता के कारण शायद 'const' का उपयोग करके कुछ त्रुटि मारा। [यह उत्तर] देखें (http://stackoverflow.com/a/37517125/5272567)। 'कॉन्स्ट' को हटाकर "निश्चित" यह निश्चित रूप से है कि वेरिएबल 'const' नहीं है। – Matthias

1

Data का प्रत्येक उदाहरण अपने स्वयं के गैर स्थैतिक सदस्य चर की आवश्यकता है जो इसकी आईडी संग्रहीत करता है। static वैरिएबल का उपयोग अंतिम उपयोग आईडी को स्टोर करने के लिए किया जा सकता है जिसे Data के निर्माता में बढ़ाया जाएगा।

एक static काउंटर, जो धागे की सुरक्षित नहीं है के बजाय

, boost's uuid उपयोग करने पर विचार:

#include <boost/lexical_cast.hpp> 
#include <boost/uuid/uuid.hpp> 
#include <boost/uuid/uuid_generators.hpp> 
#include <boost/uuid/uuid_io.hpp> 

using boost::lexical_cast; 
using boost::uuids::uuid; 
using boost::uuids::random_generator; 

std::string id_ = lexical_cast<std::string>((random_generator())()); 
-1

जहां उदाहरण (गैर स्थिर) आईडी यहाँ है? आप अपने निर्माता में तो यह

int m_ID; 

की तरह एक नया उदाहरण आईडी क्षेत्र घोषित करने के लिए की जरूरत है

Data(){m_ID = ::InterlockedIncrement(&ID);} 
एक interlocked या अन्य धागे की सुरक्षित तरीके से

+0

अच्छा विचार है, लेकिन यह पोर्टेबल कितना है? – Brady

+1

बिल्कुल पोर्टेबल नहीं ;-) मैं बस एक उदाहरण दे रहा था। – Bond

1

एक समारोह के भीतर स्थिर चर का प्रारंभ इसकी अनुमति है इसलिए समाधान

class Data 
{ 
    private: 
    static int ID() 
    { 
     static int ID = 0; 
     return ID ++; 
    } 
    int myId; 

    public: 
    Data(): myId (ID()) 
    {  
    } 
};