কোন ক্লাসে কনস্ট মেম্বার ভেরিয়েবল কীভাবে আরম্ভ করবেন?


105
#include <iostream>

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

  T1()
  {

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

যখন আমি কনস্টের সদস্য ভেরিয়েবলটি t100 দিয়ে আরম্ভ করার চেষ্টা করছি । তবে এটি আমাকে নিম্নলিখিত ত্রুটি দিচ্ছে:

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

আমি কীভাবে একটি constমান শুরু করতে পারি ?


8
সি ++ 11 দিয়ে এটি সম্ভব এই লিঙ্কটি চেক করুন stackoverflow.com/questions/13662441/…
কাপিল

উত্তর:


122

constপরিবর্তনশীল নির্দিষ্ট করে একটি পরিবর্তনশীল সংশোধনযোগ্য বা না কিনা। নির্ধারিত ধ্রুবক মানটি প্রতিবার ভেরিয়েবলটি রেফারেন্স হিসাবে ব্যবহৃত হবে। প্রোগ্রাম কার্যকর করার সময় নির্ধারিত মানটি পরিবর্তন করা যায় না।

বাজনার স্ট্রাস্ট্রপের ব্যাখ্যা এর সংক্ষিপ্ত বিবরণ যোগ করে:

একটি শ্রেণি সাধারণত একটি শিরোনাম ফাইলে ঘোষিত হয় এবং একটি শিরোনাম ফাইল সাধারণত অনেক অনুবাদ ইউনিটে অন্তর্ভুক্ত থাকে। তবে জটিল লিঙ্কারের নিয়মগুলি এড়ানোর জন্য, সি ++ এর প্রয়োজন প্রতিটি বস্তুর একটি অনন্য সংজ্ঞা রয়েছে। এই নিয়মটি ভঙ্গ হবে যদি সি ++ সত্তাগুলির শ্রেণীর সংজ্ঞা দেয় যা অবজেক্ট হিসাবে মেমোরিতে সঞ্চয় করা দরকার।

constশ্রেণীর মধ্যে একটি পরিবর্তনশীল ঘোষণা করতে হয় তবে এটি এর মধ্যে সংজ্ঞা দেওয়া যায় না। আমাদের ক্লাসের বাইরে কনস্টের ভেরিয়েবল নির্ধারণ করতে হবে।

T1() : t( 100 ){}

এখানে অ্যাসাইনমেন্ট t = 100প্রাথমিক শ্রেণীর তালিকায় ঘটে, ক্লাস সূচনা হওয়ার আগে তার অনেক আগে।


3
Here the i = 10 assignment in initializer list happens much before the class initilizaiton occurs.আমি এই পেতে চাই না শেষ বিবৃতিতে আপনি কিছুটা বিস্তৃত হতে পারেন । এবং মূলত শ্রেণীর মধ্যে সেই ধরণের সংজ্ঞা সংজ্ঞা নির্দিষ্ট করে সঠিক সংকলক হয়?
চৈতন্য

3
আমি = 10 কাজ কী?
ড্যানিয়েল দারানাস

আমার ক্লাসে আমার ধ্রুবক রয়েছে যা আমি উপরের উপায়ে শুরু করি। যাইহোক, আমি যখন class শ্রেণীর একটি অবজেক্ট তৈরি করার চেষ্টা করি তখন এটি operator = function not foundভিসি ++ তে বলে আমাকে ত্রুটি দেয় । কি সমস্যা হতে পারে?
রোহিত শিন্ডে

4
আপনি যখন কারও কারও সঠিক শব্দটি অ্যাট্রিবিউট ব্যতীত ব্যবহার করেন, তখন তাকে চৌর্যবৃত্তি বলা হয়। সঠিক স্বীকৃতিপ্রদান ব্যবহার করুন - দেখুন stroustrup.com/bs_faq2.html#in-class এবং stackoverflow.com/questions/13662441/...
টানায়

হ্যাঁ, আমিও উত্তরে কোডটি পুরোপুরি বুঝতে পারি না - ওটা কী? এটি সিপিপি ফাইল প্রয়োগে স্থাপন করা যেতে পারে?
টোমা জ্যাটো - মনিকা

50

ভাল, আপনি এটি করতে পারে static:

static const int t = 100;

অথবা আপনি সদস্য আরম্ভকারী ব্যবহার করতে পারেন:

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

2
তার ব্যবহারের জন্য (এবং / অথবা উদ্দেশ্য), এটি স্থির করা আরও ভাল।
মার্ক গার্সিয়া

@ ফ্রেডলারসন কি এটির মতো কিছু জি ++ সংস্করণগুলি এ জাতীয় প্রারম্ভিককরণের অনুমতি দেয় না? নাকি একেবারেই অনুমোদিত নয়?
চৈতন্য

3
@ চৈতন্য: সি ++ 11 নন-স্ট্যাটিক সদস্য ইনিশিয়ালাইজারগুলি জিসিসি ৪.7 থেকে প্রয়োগ করা হয়েছে।
জেসি গুড

@ মার্কগার্সিয়া কেন আরও ভাল? এটি প্রয়োজনে হতে পারে যদি 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 মানের একটি অংশ?
serup

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
স্ফটিক পরিষ্কার উদাহরণগুলির জন্য আপনাকে ধন্যবাদ, এবং বৈচিত্রটি বহুত্ব দেখায়! অস্পষ্টতা এবং অতিরিক্ত গবেষণা / পাঠকের অংশে স্ক্রোলিং নির্মূল!
clearlight

13
  1. আপনি আপনার সংকলকটি সি ++ 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তবে ঘোষণার সময় আপনি কনস সদস্যকে আরম্ভ করতে পারবেন না। সুতরাং এখানে এটি কনস্ট্রাক্টর অবশ্যই কনস্ট্রের ডেটা মেম্বারকে আরম্ভ করার প্রয়োজন make T1():t(100)তাত্ক্ষণিকভাবে স্মৃতি পাওয়ার জন্য ইনিশিয়ালের তালিকাটি ব্যবহার করা আবশ্যক ।


0

আপনি staticএই শ্রেণীর সদস্যের ভেরিয়েবলের সূচনাটি সম্ভব করতে যোগ করতে পারেন।

static const int i = 100;

তবে শ্রেণি ঘোষণার অভ্যন্তরে ব্যবহার করা এটি সর্বদা ভাল অনুশীলন নয়, কারণ শ্রেণি থেকে আগত সমস্ত বস্তু একই স্থিতিশীল ভেরিয়েবলটি ভাগ করে নেবে যা তাত্ক্ষণিকৃত বস্তুর স্কোপ মেমরির বাইরে অভ্যন্তরীণ মেমরিতে সঞ্চিত থাকে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.