क्लास में कॉन्स्टेबल मेंबर वेरिएबल को इनिशियलाइज़ कैसे करें?


105
#include <iostream>

using namespace std;
class T1
{
  const int t = 100;
  public:

  T1()
  {

    cout << "T1 constructor: " << t << endl;
  }
};

जब मैं कॉन्स्टेबल सदस्य चर tको 100 के साथ इनिशियलाइज़ करने की कोशिश कर रहा हूँ। लेकिन यह मुझे निम्न त्रुटि दे रहा है:

test.cpp:21: error: ISO C++ forbids initialization of member t
test.cpp:21: error: making t static

मैं एक constमूल्य कैसे शुरू कर सकता हूं ?


8
c ++ 11 के साथ यह संभव जाँच इस लिंक है stackoverflow.com/questions/13662441/...
कपिल

जवाबों:


122

constचर निर्दिष्ट एक चर परिवर्तनीय है या नहीं। प्रत्येक बार चर को संदर्भित करने के लिए निर्दिष्ट निरंतर मूल्य का उपयोग किया जाएगा। असाइन किया गया मान प्रोग्राम निष्पादन के दौरान संशोधित नहीं किया जा सकता है।

बज़्ने स्ट्रॉस्ट्रुप की व्याख्या इसे संक्षेप में प्रस्तुत करती है:

हेडर फ़ाइल में आमतौर पर एक वर्ग घोषित किया जाता है और हेडर फ़ाइल को आमतौर पर कई अनुवाद इकाइयों में शामिल किया जाता है। हालांकि, जटिल लिंकर नियमों से बचने के लिए, C ++ के लिए आवश्यक है कि प्रत्येक ऑब्जेक्ट की एक अनूठी परिभाषा हो। उस नियम को तोड़ा जाएगा यदि C ++ को उन संस्थाओं की इन-क्लास परिभाषा की अनुमति दी जाए जिन्हें स्मृति में वस्तुओं के रूप में संग्रहीत करने की आवश्यकता है।

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

T1() : t( 100 ){}

यहाँ असाइनमेंट t = 100इनिशियलाइज़र लिस्ट में होता है, बहुत पहले क्लास इंट्राइजेशन होने के बाद।


3
क्या आप Here the i = 10 assignment in initializer list happens much before the class initilizaiton occurs.इस कथन के अंतिम विवरण पर थोड़ा विस्तृत हो सकते हैं । और मूल रूप से वर्ग के भीतर परिभाषाओं को अनुमति देने का एक प्रकार संकलक विशिष्ट अधिकार है?
चैतन्य

3
क्या मैं = 10 असाइनमेंट?
डैनियल डारनास

मेरी कक्षा में मेरे पास निरंतरता है जो मैं उपरोक्त तरीके से शुरू करता हूं। हालाँकि, जब मैं उस वर्ग का ऑब्जेक्ट बनाने की कोशिश करता हूं, तो यह मुझे एक त्रुटि देता है जो कहता है कि operator = function not foundVC ++ में। क्या समस्या हो सकती है?
रोहित शिंदे

4
जब आप किसी के सटीक शब्दों का उपयोग बिना किसी विशेषता के करते हैं, तो इसे साहित्यिक चोरी कहा जाता है। कृपया उचित एट्रिब्यूशन का उपयोग करें - देखें stroustrup.com/bs_faq2.html#in-class और stackoverflow.com/questions/13662441/…
तान्या

हाँ, मैं भी जवाब में कोड पूरी तरह से समझ में नहीं आता - वह क्या है? क्या इसे cpp फ़ाइल कार्यान्वयन में रखा जा सकता है?
टॉम ज़ातो -

50

खैर, आप इसे बना सकते हैं static:

static const int t = 100;

या आप एक सदस्य आरंभीकरण का उपयोग कर सकते हैं:

T1() : t(100)
{
    // Other constructor stuff here
}

2
उनके उपयोग (और / या इरादे) के लिए, इसे स्थिर बनाने के लिए बेहतर होगा।
मार्क गार्सिया

@FredLarson क्या यह कुछ g ++ संस्करणों की तरह है जो इस तरह की आरंभिक अनुमति नहीं देता है? या इसकी अनुमति बिल्कुल नहीं है?
चैतन्य

3
@चैतन्य: C ++ 11 गैर-स्थैतिक सदस्य आरंभिकों को gcc 4.7 से कार्यान्वित किया जाता है।
जेसी गुड

@MarkGarcia क्यों बेहतर? यह आवश्यकता पर हो सकता है यदि const memberकार्यों / वस्तुओं से सुलभ होना चाहिए तो स्थिर क्यों?
आसिफ मुश्ताक

हालांकि आमतौर पर यह स्थैतिक की शुरुआत करने वालों के लिए एक उदाहरण देने के लिए भ्रामक है। क्योंकि, उन्हें पता नहीं हो सकता है कि यह उस वर्ग के सभी उदाहरणों (वस्तुओं) के लिए केवल एक है।
मुहम्मद सिक्क

30

क्लास के अंदर कॉन्स्टेबल सदस्यों को इनिशियलाइज़ करने के कुछ तरीके हैं।

सामान्य रूप से कांस्टेबल सदस्य की परिभाषा, चर के आरंभीकरण की आवश्यकता है।

1) वर्ग के अंदर, यदि आप कास्ट को इनिशियलाइज़ करना चाहते हैं तो सिंटैक्स ऐसा होता है

static const int a = 10; //at declaration

2) दूसरा तरीका हो सकता है

class A
{
  static const int a; //declaration
};

const int A::a = 10; //defining the static member outside the class

3) यदि आप घोषणा पर आरंभीकरण नहीं करना चाहते हैं, तो दूसरा तरीका कंस्ट्रक्टर के माध्यम से है, चर को आरंभीकरण सूची (कंस्ट्रक्टर के शरीर में नहीं) में आरंभीकृत करने की आवश्यकता है। ऐसा होना ही है

class A
{
  const int b;
  A(int c) : b(c) {} //const member initialized in initialization list
};

8
मुझे लगता है कि इस उत्तर को स्पष्टीकरण की आवश्यकता है। क्लास सदस्य के लिए स्थिर कीवर्ड का उपयोग कंपाइलर को खुश करने के लिए कुछ मनमाना वाक्यविन्यास नहीं जोड़ रहा है। इसका अर्थ है कि वस्तु के सभी उदाहरणों के लिए चर की एक ही प्रति है, स्थिर या नहीं। यह एक डिजाइन विकल्प है जिसे सावधानी से विचार करने की आवश्यकता है। रेखा के नीचे प्रोग्रामर यह तय कर सकता है कि यह स्थिर वर्ग सदस्य किसी वस्तु के जीवनकाल के लिए स्थिर रहने के बावजूद, विभिन्न वस्तुओं के साथ भिन्न हो सकता है।
opetrenko

सहमत .. जब हम स्थैतिक का उपयोग करते हैं, तो यह सभी वस्तुओं के लिए इसकी केवल एक प्रति बनाता है .. जैसा कि आपने इसकी डिज़ाइन पसंद का उल्लेख किया है। सभी वस्तुओं 1 और 2 के लिए एकल प्रति के मामले में काम करना चाहिए। प्रत्येक वस्तु के लिए अलग-अलग प्रति के मामले में, 3 काम करेगा
ravs2627

यह उत्तर परिणाम के बिना एक सरल वाक्यविन्यास परिवर्तन का सुझाव देता है - जबकि इसे स्थिर होने के लिए बदलना नहीं है।
इसहाक वुड्स

क्या होगा यदि आपको डबल या फ्लोट का उपयोग करने की आवश्यकता है - क्या यह सी ++ 11 मानक का एक हिस्सा है?
नागिन

14

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

class Example{
      const int x;
    public:
      Example(int n);
};

Example::Example(int n):x(n){
}

यदि constकक्षा में कई डेटा सदस्य हैं, तो आप सदस्यों को आरम्भ करने के लिए निम्नलिखित सिंटैक्स का उपयोग कर सकते हैं:

Example::Example(int n, int z):x(n),someOtherConstVariable(z){}

3
मुझे लगता है कि यह स्वीकार किए जाते हैं की तुलना में बेहतर उत्तर प्रदान करता है ....
इयान

1
क्रिस्टल स्पष्ट उदाहरणों के लिए धन्यवाद, और बहुतायत दिखाने वाला संस्करण! पाठक की ओर से अस्पष्टता और अतिरिक्त अनुसंधान / स्क्रॉलिंग को हटा दिया गया!
स्पष्ट

13
  1. आप C ++ 11 का समर्थन करने के लिए अपने कंपाइलर को अपग्रेड कर सकते हैं और आपका कोड पूरी तरह से काम करेगा।

  2. निर्माण में आरंभीकरण सूची का उपयोग करें।

    T1() : t( 100 )
    {
    }

6

एक और उपाय है

class T1
{
    enum
    {
        t = 100
    };

    public:
    T1();
};

इसलिए टी को 100 से शुरू किया जाता है और इसे बदला नहीं जा सकता है और यह निजी है।


3

यदि कोई सदस्य एरियर है तो यह सामान्य से थोड़ा जटिल होगा:

class C
{
    static const int ARRAY[10];
 public:
    C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};

या

int* a = new int[N];
// fill a

class C {
  const std::vector<int> v;
public:
  C():v(a, a+N) {}
};

2

एक अन्य संभावित तरीका नाम स्थान है:

#include <iostream>

namespace mySpace {
   static const int T = 100; 
}

using namespace std;

class T1
{
   public:
   T1()
   {
       cout << "T1 constructor: " << mySpace::T << endl;
   }
};

नुकसान यह है कि यदि हेडर फ़ाइल शामिल है तो अन्य वर्ग भी स्थिरांक का उपयोग कर सकते हैं।


1

यह करने का सही तरीका है। आप इस कोड को आज़मा सकते हैं।

#include <iostream>

using namespace std;

class T1 {
    const int t;

    public:
        T1():t(100) {
            cout << "T1 constructor: " << t << endl;
        }
};

int main() {
    T1 obj;
    return 0;
}

यदि आप उपयोग कर रहे हैं C++10 Compiler or belowतो आप घोषणा के समय आम सदस्य को इनिशियलाइज़ नहीं कर सकते हैं। तो यहाँ कांस्ट डाटा मेंबर को इनिशियलाइज़ करने के लिए कंस्ट्रक्टर बनाना होगा। T1():t(100)इंस्टेंट पर मेमोरी प्राप्त करने के लिए इनिशियल लिस्ट का उपयोग करना भी आवश्यक है ।


0

आप staticइस वर्ग के सदस्य चर के आरंभीकरण को संभव बनाने के लिए जोड़ सकते हैं ।

static const int i = 100;

हालाँकि, यह हमेशा क्लास डिक्लेरेशन के अंदर उपयोग करने के लिए एक अच्छा अभ्यास नहीं है, क्योंकि उस क्लास से निकाले गए सभी ऑब्जेक्ट एक ही स्टैटिक वेरिएबल को शेयर करेंगे, जो कि इंस्टेंटेड ऑब्जेक्ट्स के स्कोप मेमोरी के बाहर इंटरनल मेमोरी में स्टोर होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.