C++

2010-08-21 14 views
22

मैं इस तरह एक सार्वजनिक स्थैतिक चर को परिभाषित करने के कोशिश कर रहा हूँ स्थिर सदस्यों को परिभाषित करना:C++

public : 
     static int j=0;  //or any other value too 

मैं यह बहुत ही लाइन पर एक संकलन त्रुटि हो रही है: आईएसओ सी ++ मनाही गैर स्थिरांक स्थिर की कक्षा प्रारंभ सदस्य 'जे'।

  1. सी ++ में इसकी अनुमति क्यों नहीं है?

  2. क्यों कॉन्स्ट सदस्यों को प्रारंभ करने की अनुमति है?

  3. क्या इसका मतलब है सी ++ में स्थिर चर 0 में सी के रूप में प्रारंभ नहीं किए गए हैं?

धन्यवाद!

उत्तर

14

(1.) सी ++ में इसकी अनुमति क्यों नहीं है?

Bjarne Stroustrup's C++ Style and Technique FAQ से

: A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

(2.) क्यों स्थिरांक सदस्यों की अनुमति दी जाती प्रारंभ?

[dirkgently said it better]

(3.) इसका मतलब यह है स्थैतिक चर C++ सी में के रूप में 0 के साथ आरंभ नहीं कर रहे हैं?

जहाँ तक मुझे पता है, जब तक आप एक सीपीपी में स्थिर सदस्य वर की घोषणा यह शून्य से आरंभ नहीं करता है, तो आप अन्यथा निर्दिष्ट नहीं करते हो जाएगा:

// in some .cpp 
int Test::j; // j = int(); 
+0

महान उत्तर के लिए धन्यवाद, आपने मुझे मेरे सिर से मेरी सुनवाई खींचने से रोका! मेरे पास एक सवाल है, क्या संदर्भ सदस्यों को परिभाषित करते समय शून्य सूचक की आपूर्ति करने का कोई संभावित तरीका है? –

+1

@TimVisee सुनिश्चित नहीं हैं कि अगर यह संभव है - कम से कम एक पोर्टेबल, गैर यूबी तरह से - लेकिन आप गलत संदर्भ में पहुंचते हैं। यदि आप नल सेमेन्टिक्स चाहते हैं तो बस एक पॉइंटर का उपयोग करें या शायद बूस्ट वैकल्पिक जैसे कुछ का उपयोग करें। –

16

आपको एक .cpp फ़ाइल में स्थैतिक चर प्रारंभ करना होगा, न कि कक्षा घोषणा में।

जब आप कक्षा में स्थिर चर घोषित करते हैं, तो इसका उपयोग कक्षा को तत्काल किए बिना किया जा सकता है।

//Header file 
class Test 
{ 
    public: 
    static int j; 
}; 

//In cpp file 

//Initialize static variables here. 
int Test::j = 0; 

//Constructor 
Test::Test(void) 
{ 
    //Class initialize code 
} 
17

ऐसा क्यों है सी ++ में अनुमति नहीं है?

जब तक आप इसे परिभाषित नहीं करते हैं, तब तक वेरिएबल एल-वैल्यू नहीं बनता है।

कॉन्स्ट सदस्यों को प्रारंभ करने की अनुमति क्यों दी जाती है?

इस मामले में भी, यदि आप चर के पते को लेने जा रहे हैं तो एक परिभाषा आवश्यक है।

9.4.2 स्टेटिक डेटा सदस्यों

एक स्थिर डेटा की घोषणा अपने वर्ग परिभाषा सदस्य एक परिभाषा नहीं है और एक अधूरा सीवी के अलावा अन्य प्रकार की हो सकती है - योग्य शून्य। की परिभाषा एक स्थिर डेटा सदस्य नामस्थान स्कोप में सदस्य की कक्षा परिभाषा को संलग्न करेगा। नामस्थान स्कोप की परिभाषा में, स्थिर डेटा सदस्य का नाम योग्यता से ऑपरेटर का उपयोग करके अपने वर्ग के नाम से योग्य होगा। एक स्थिर डेटा सदस्य की परिभाषा में प्रारंभकर्ता अभिव्यक्ति अपने वर्ग

इसके अलावा के दायरे में है, यह मुख्य रूप से एक उपयोग विरूपण साक्ष्य है, ताकि आप लिख सकते हैं:

class S { 
     static const int size = 42; 
     float array[ size ]; 
}; 

करता है इसका मतलब है सी ++ में स्थिर चर 0 में के साथ शुरू नहीं किया गया है?

नहीं वे हैं:

गैर स्थानीय चर स्थिर भंडारण अवधि (3.7.1) या धागा भंडारण अवधि (3.7 के साथ

चर के

3.6.2 प्रारंभ। 2) zeroinitialized किया जाएगा (8.5) से पहले किसी अन्य प्रारंभ जगह लेता है।

हालांकि चीजें सी ++ 0x में थोड़ा और अधिक कठिन हो जाती हैं। सभी शाब्दिक प्रकार अब प्रारंभ किया जा सकता है जो मतलब यह होगा कि सभी अदिश प्रकार (तैरता शामिल) (के रूप में वर्तमान मानक में केवल अभिन्न प्रकार के खिलाफ) और कुछ वर्ग प्रकार अब घोषणा में एक प्रारंभकर्ता का उपयोग कर प्रारंभ किया जा सकता है।

+0

अगर पता नहीं लिया जाता है क्यों स्थिर स्थिरांक पूर्णांक के लिए परिभाषा की आवश्यकता नहीं है? यह (.h) में परिभाषित स्थिर-const-int संकलन, परिभाषा के बिना सफलतापूर्वक लिंक। यदि हां, के बाद से, जब सी ++ परिभाषा के बिना घोषणा के इस प्रकार, सी ++ 98 के बाद से अनुमति देता है? सी ++ 03 के बाद से? प्रामाणिक स्रोत कृपया। सी ++ मानक (9.4.2) कंपाइलर्स के साथ सिंक में नहीं है। यह उल्लेख करता है कि यदि सदस्य कार्यक्रम में उपयोग किया जाता है तो सदस्य को अभी भी परिभाषित किया जाएगा। तो, मैं आपको बताउंगा, मैं सी ++ मानक से उद्धरण की तलाश नहीं कर रहा हूं। अच्छा होगा, जीसीसी चेंजलॉग/सी ++ कमेटी नोट्स। – smRaj

8

संक्षिप्त उत्तर:

यह extern int Test_j = 0; कह के बराबर है।

यदि यह संकलन किया था, तो क्या होगा? आपकी कक्षा की हेडर फ़ाइल समेत प्रत्येक स्रोत फ़ाइल टेस्ट :: जे नामक प्रतीक को परिभाषित करेगी। लिंकर इसे पसंद नहीं करता है।

+4

+1।इस मुद्दे की प्रकृति पर 'बाहरी' प्रकाश प्रकाश डालता है। – Cheezmeister

2
class GetData   
{  
private:  
static int integer; //Static variable must be defined with the extension of keyword static;  
public:  
static void enter(int x)  
{  
integer = x; //static variable passed through the static function  
} 
static int show() //declared and defined 
{ 
    return integer; //will return the integer's value 
}   
};   
int GetData::integer = 0; //Definition of the static variable  
int main()  
{  
    GetData::enter(234); //value has been passed through the static function enter. Note that class containing static variables may not have the object in main. They can be called by scope resolution operator in main. 
    cout<<GetData::show();  
}