2011-11-25 12 views
12

सी और सी ++ में सभी स्थैतिक चर डिफ़ॉल्ट रूप से शून्य पर प्रारंभ किए जाते हैं।मुझे सी ++ में स्थिर वर्ग चर क्यों शुरू करना चाहिए?

यह स्थिर वर्ग डेटा सदस्यों का मामला नहीं है। ऐसा क्यों है?

#include <iostream> 
using namespace std; 

int var; 

class MyClass 
{ 
public: 
    static int classVar; 
}; 
int MyClass::classVar = 0; // Why I have to init it here? 

int main(void) 
{ 
    cout << ::var << endl;   // this is initalized to ZERO by default 
    static int var; 
    cout << var << endl;   // and this also is initalized to Zero 
    cout << MyClass::classVar << endl; 

    return 0; 
} 
+0

आपको यकीन नहीं है ** var ** को 0 से शुरू किया गया है। यह संभव है, कभी-कभी संभावित, लेकिन सुनिश्चित नहीं है। –

+3

@AlessandroPezzato: दरअसल, मानक गतिशील प्रारंभिक निष्पादन से पहले सभी वैश्विक चर के लिए स्मृति को शून्य करने के बारे में स्पष्ट है ... उन अंतर्निर्मितों के अलावा जिनके लिए एक शाब्दिक मूल्य प्रभावित होता है, मुझे लगता है कि वे सीधे प्रभावित हो सकते हैं (नीचे जैसा कि नियम है) क्योंकि यह अनावश्यक है। –

उत्तर

21

वर्ग दायरे में

int MyClass::classVar = 0; // Why I have to init it here? 

एक परिभाषा और

static int classVar; 

एक घोषणा, यानी है। एक वचन वैरिएबल परिभाषित किया जाएगा: आपको को एक बार परिभाषित करने वाले चर को परिभाषित करना होगा।

तर्क यह है कि कक्षा घोषणा कई स्रोत फ़ाइलों में शामिल की जाएगी। इसका एक हिस्सा एक परिभाषा होगी, यह गुणा हो जाएगा: यह गलत है (अपवाद इनलाइन [सदस्य] फ़ंक्शंस हैं)।

ध्यान दें कि मूल्य प्रारंभ नियमों के अनुसार, आप

int MyClass::classVar; // Zero-initialized ! 
एक परिभाषा के रूप में

के साथ मिल सकता है।

चर नाम स्थान गुंजाइश पर घोषित कर दिया परिभाषाएँ भी कर रहे हैं (जब तक कि वे extern योग्य हैं):

int var; 

एक घोषणा है, और एक परिभाषा है: आप एक हैडर में डाल और कई अनुवाद इकाइयों में शामिल हैं, आपके पास एक त्रुटि है ("परिभाषित प्रतीक गुणा करें", या उन पंक्तियों के साथ कुछ)।

[ध्यान दें कि C++ (और सी में नहीं), अगर var ऊपर const है, यह स्वतः ही static हो जाता है और वहाँ एक परिभाषा नियम का कोई उल्लंघन नहीं यह एक गुणा शामिल हैडर में रखा जाना चाहिए है। यह थोड़ा विषय बंद हो जाता है, लेकिन विवरण

+2

मुझे यकीन नहीं है कि क्या पूछा जा रहा है। मैंने पढ़ा कि "मुझे' = 0 क्यों रखना है, 'वहां? " – Mat

+0

@Alexandre सी .: यह अच्छा होगा अगर आप यह भी समझाएं कि इसकी आवश्यकता क्यों है। – Nawaz

+3

तो, 'int MyClass :: classVar;' यदि आपको केवल शून्य-प्रारंभिक आवश्यकता है तो पहले से ही पर्याप्त होना चाहिए? कभी कोशिश नहीं की लेकिन एसडीडी और एक हटाए गए उत्तर के अनुसार, यह वास्तव में करता है। – zerm

6

सी ++ पूछे जाने वाले प्रश्न 10.12 कहा गया है कि पूछने के लिए] के लिए स्वतंत्र महसूस:

स्थिर डेटा सदस्यों को स्पष्ट रूप से ठीक एक संकलन इकाई में परिभाषित किया जाना चाहिए।

From C++ FAQ http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

है कि आपके सवाल का जवाब या सी ++ मानक खुद के लिए एक संदर्भ के बाद आप थे करता है?

2

आपको अपने स्थैतिक वर्ग डेटा चर प्रारंभ करना होगा, क्योंकि आपको संकलक को यह बताना होगा कि उनका मूल्य क्या है। कक्षाओं को डिफ़ॉल्ट मान की धारणा नहीं है।

चर प्रकार int के लिए यह 0 है, double 0.0 के लिए, एक string "" आदि इसके विपरीत के लिए, एक तार्किक "शून्य मान" है, वर्गों जरूरी एक डिफ़ॉल्ट मान नहीं है। उदाहरण के लिए, उदाहरण के लिए class Rectangle पर विचार करें। इसका शून्य मान क्या है - शून्य वर्ग के साथ एक आयताकार या इकाई की लंबाई के साथ एक आयताकार?स्थैतिक चर के लिए, एक कंपाइलर आपको स्वयं को परिभाषित करने के लिए कहता है, आपके स्थैतिक चर का क्या मूल्य होना चाहिए, क्योंकि प्रत्येक डेटा प्रकार को डिफ़ॉल्ट मान द्वारा प्रारंभ नहीं किया जा सकता है।

+1

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

+0

स्थिर चर को परिभाषित किया जाना चाहिए। निर्माता इसे प्रारंभ नहीं करेंगे। उदाहरण नीचे पर विचार करें ... "पूर्णांक परीक्षण :: k;" यदि। यह संकलन नहीं होगा टिप्पणी की हो जाएगा कक्षा की परीक्षा { सार्वजनिक: स्थैतिक int k; }; int test :: k; int मुख्य() { परीक्षण टी; cout << t.k; वापसी 0; } – rakesh

+0

@ विक्टर हाँ, आप सही हैं, मुझे यह नोट करने के लिए धन्यवाद। सवाल एक स्थैतिक चर परिभाषित करने के बारे में था, न कि इसकी शुरुआत। –

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