সদস্য ফাংশনে স্থির পরিবর্তনশীল vari


158

কেউ দয়া করে ব্যাখ্যা করতে পারেন যে কীভাবে সদস্য ফাংশনে স্থির পরিবর্তনশীল সি ++ এ কাজ করে।

নিম্নলিখিত শ্রেণীর দেওয়া:

class A {
   void foo() {
      static int i;
      i++;
   }
}

যদি আমি একাধিক উদাহরণ ঘোষণা করি A, তবে কোনও foo()এক উদাহরণে ডেকে আনা iহলে সমস্ত দৃষ্টান্তে স্থির পরিবর্তনশীল বৃদ্ধি পায় ? নাকি কেবল যার একেই বলা হয়েছিল?

আমি ধরে নিয়েছি যে প্রতিটি উদাহরণের নিজস্ব অনুলিপি থাকবে i, তবে আমি মনে করি যে কোনও কোডের মধ্য দিয়ে পদক্ষেপ নেওয়া অন্যথায় ইঙ্গিত করে indicate

উত্তর:


169

যেহেতু class Aএকটি অ-টেম্পলেট শ্রেণি এবং A::foo()এটি একটি নন-টেম্পলেট ফাংশন। static int iপ্রোগ্রামের ভিতরে কেবল একটি অনুলিপি থাকবে ।

কোনও Aবস্তুর উদাহরণ একইরূপে প্রভাব ফেলবে iএবং এর আজীবন iপ্রোগ্রামের মধ্য দিয়েই থাকবে। একটি উদাহরণ যুক্ত করতে:

A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 2
o3.foo(); // i = 3
o1.foo(); // i = 4

3
ভাল উদাহরণের জন্য ধন্যবাদ! প্রকৃতপক্ষে এমন কিছু অর্জন করার কোনও উপায় আছে static int iযা উদাহরণের সাথে নির্দিষ্টতার ক্ষেত্রকে নির্দিষ্ট করে, যাতে উদাহরণস্বরূপ o1.foo(); // i = 1এবং $o2.foo(); // i = 1...?
স্টিংজারি

14
যদিও আপনি যে শৈলীটি সন্ধান করছেন এটি এটি নাও হতে পারে, তবে ক্লাস এ এর ​​ব্যক্তিগত ডেটা সদস্য তৈরি করার ফলে আপনি যে বর্ণনাটি দিচ্ছেন তা তার প্রভাব ফেলবে। আপনি যদি নাম দ্বন্দ্ব নিয়ে উদ্বিগ্ন হন তবে আপনি একটি উপসর্গ যুক্ত করতে পারেন যেমন m_i এর স্থিতি নির্দেশ করতে।
কার্ল মরিস

137

staticদুর্ভাগ্যক্রমে কী- ওয়ার্ডটির সি ++ তে কয়েকটি ভিন্ন সম্পর্কহীন অর্থ রয়েছে

  1. যখন ডেটা সদস্যদের জন্য ব্যবহার করা হয় তখন এর অর্থ হ'ল ডেটা ক্লাসে বরাদ্দ করা হয় এবং উদাহরণ হিসাবে নয়।

  2. যখন কোনও ফাংশনের অভ্যন্তরে ডেটা ব্যবহার করা হয় তখন এর অর্থ হ'ল ডেটাটি স্থিতিশীলভাবে বরাদ্দ করা হয়, প্রথম বার ব্লকটি প্রবেশ করার পরে আরম্ভ না করা হয় এবং প্রোগ্রামটি বন্ধ না হওয়া পর্যন্ত স্থায়ী হয়। এছাড়াও ভেরিয়েবলটি কেবল ফাংশনের অভ্যন্তরে দৃশ্যমান। স্থানীয় স্ট্যাটিক্সের এই বিশেষ বৈশিষ্ট্যটি প্রায়শই সিলেটলেটগুলির অলস নির্মাণ বাস্তবায়নের জন্য ব্যবহৃত হয়।

  3. সংকলন ইউনিট স্তরে (মডিউল) ব্যবহৃত হলে এর অর্থ হল ভেরিয়েবলটি একটি গ্লোবালের মতো (যেমন বরাদ্দকৃত এবং প্রাথমিকভাবে mainচালানো হয় এবং mainপ্রস্থানের পরে ধ্বংস হয় ) তবে পরিবর্তনশীলটি অন্য সংকলন ইউনিটে অ্যাক্সেসযোগ্য বা দৃশ্যমান হবে না

আমি প্রতিটি ব্যবহারের জন্য সবচেয়ে গুরুত্বপূর্ণ যে অংশটি কিছুটা জোর দিয়েছি। ব্যবহার (3) কিছুটা নামবিহীন নেমস্পেসের পক্ষে নিরুৎসাহিত করা হয়েছে যা অ-রফতানি শ্রেণীর ঘোষণার জন্যও অনুমতি দেয়।

আপনার কোডে staticকীওয়ার্ডটি 2 নম্বর অর্থের সাথে ব্যবহৃত হয় এবং ক্লাস বা উদাহরণগুলির সাথে কিছুই করার থাকে না ... এটি ফাংশনের একটি পরিবর্তনশীল এবং এর কেবল একটি অনুলিপি থাকবে।

যথাযথভাবে iammilind বলেছিল যে ফাংশনটি কোনও টেম্পলেট ফাংশন হলে সেই পরিবর্তনশীলটির একাধিক উদাহরণ থাকতে পারে (কারণ সেক্ষেত্রে প্রকৃতপক্ষে কার্যক্রমে প্রোগ্রামটি বিভিন্ন কপির মধ্যে উপস্থিত থাকতে পারে)। এমনকি কোর্সের ক্ষেত্রেও ক্লাস এবং উদাহরণগুলি অপ্রাসঙ্গিক ... নীচের উদাহরণটি দেখুন:

#include <stdio.h>

template<int num>
void bar()
{
    static int baz;
    printf("bar<%i>::baz = %i\n", num, baz++);
}

int main()
{
    bar<1>(); // Output will be 0
    bar<2>(); // Output will be 0
    bar<3>(); // Output will be 0
    bar<1>(); // Output will be 1
    bar<2>(); // Output will be 1
    bar<3>(); // Output will be 1
    bar<1>(); // Output will be 2
    bar<2>(); // Output will be 2
    bar<3>(); // Output will be 2
    return 0;
}

41
keyword static unfortunately has a few different unrelated meanings in C++:) জন্য +1
iammilind

এই পড়ার পরে পৃথিবী আরও অনেক বেশি অর্থবোধ করে, আপনাকে ধন্যবাদ
এরিন

আমি টেমপ্লেটগুলি সহ কৌশলটি পছন্দ করি। আমি এটি ব্যবহারের অজুহাত খুঁজতে অপেক্ষা করতে পারি না।
টোমা জ্যাটো - মনিকা

"নামবিহীন নেমস্পেসের পক্ষে কিছুটা নিরুৎসাহিত" এর জন্য যে কেউ রেফারেন্স পেয়েছেন?
অস্টিনমার্টন

3
@ অস্টিনমার্টন: "স্থানীয় থেকে অনুবাদ ইউনিট" নির্দেশ করতে স্ট্যাটিকের ব্যবহারটি সি ++ এ অবচয় করা হয়েছে instead পৃষ্ঠায় 819.
6502

2

ফাংশনের অভ্যন্তরে স্থির পরিবর্তনশীল

  • স্ট্যাটিক ভেরিয়েবলটি কোনও ফাংশনের অভ্যন্তরে তৈরি করা হয় প্রোগ্রামের স্ট্যাটিক মেমরিতে স্ট্যাকের মধ্যে নয়।

  • স্ট্যাটিক ভেরিয়েবল ইনিশিয়ালেশনটি ফাংশনের প্রথম কলটিতে করা হবে।

  • স্ট্যাটিক ভেরিয়েবল একাধিক ফাংশন কলগুলিতে মান ধরে রাখবে

  • স্ট্যাটিক ভেরিয়েবলের লাইফটাইম হ'ল প্রোগ্রাম

এখানে চিত্র বর্ণনা লিখুন

উদাহরণ

#include <iostream>

using namespace std;

class CVariableTesting 
{
    public:
    
    void FuncWithStaticVariable();
    void FuncWithAutoVariable();

};

void CVariableTesting::FuncWithStaticVariable()
{
    static int staticVar = 0; //staticVar is initialised by 0 the first time
    cout<<"Variable Value : "<<staticVar<<endl;
    staticVar++;
}
void CVariableTesting::FuncWithAutoVariable()
{
    int autoVar = 0;
    cout<<"Variable Value : "<<autoVar<<endl;
    autoVar++;
}
    

int main()
{
    CVariableTesting objCVariableTesting;
    cout<<"Static Variable";
    objCVariableTesting.FuncWithStaticVariable();
    objCVariableTesting.FuncWithStaticVariable();
    objCVariableTesting.FuncWithStaticVariable();
    objCVariableTesting.FuncWithStaticVariable();
    objCVariableTesting.FuncWithStaticVariable();
    
    cout<<endl;
    cout<<"Auto Variable";
    objCVariableTesting.FuncWithAutoVariable();
    objCVariableTesting.FuncWithAutoVariable();
    objCVariableTesting.FuncWithAutoVariable();
    objCVariableTesting.FuncWithAutoVariable();
    objCVariableTesting.FuncWithAutoVariable();
    
    return 0;
}

আউটপুট:

স্ট্যাটিক ভেরিয়েবল

পরিবর্তনশীল মান: 0
পরিবর্তনশীল মান: 1
ভেরিয়েবল মান: 2
ভেরিয়েবল মান: 3
ভেরিয়েবল মান: 4

অটো ভেরিয়েবল

ভেরিয়েবল মান: 0
ভেরিয়েবল মান: 0
ভেরিয়েবল মান: 0
ভেরিয়েবল মান: 0
ভেরিয়েবল মান: 0


-2

সরলীকৃত উত্তর:

স্ট্যাটিক ভেরিয়েবলগুলি নির্বিশেষে তারা কোনও (অ-টেম্পলেটেড) classবা একটি (অ-টেম্পলেটেড) ফাংশনের সদস্য হোন না কেন , আচরণ করুন - প্রযুক্তিগতভাবে - এমন একটি গ্লোবাল লেবেলের মতো যা স্কোপটি classবা ফাংশনটির মধ্যে সীমাবদ্ধ ।


9
না। গ্লোবালগুলি প্রোগ্রামের সূচনাতে শুরু হয়, ফাংশন স্ট্যাটিক্স প্রথম ব্যবহারে আরম্ভ করা হয়। এটি একটি বড় পার্থক্য।
6502

আমি মনে করি না যে এটি ঘটেছিল। তবে এটি যেভাবেই সংকলক নির্দিষ্ট হওয়া উচিত।
0xbadf00d

2
তারপরে আপনি ভুল ভাবেন: সি ++ স্ট্যান্ডার্ডে 3.6.1 স্থির করে যে স্ট্যাটিক স্টোরেজ সময়কাল সহ নেমস্পেস স্কোপের অবজেক্টের নির্মাণ শুরু হয়; 7.7 (৪) নির্দেশ দেয় যে সাধারণভাবে "... এ জাতীয় একটি ভেরিয়েবল প্রথমবারের মাধ্যমে নিয়ন্ত্রণের মাধ্যমে তার ঘোষণার মধ্য দিয়ে যায়; এ জাতীয় একটি ভেরিয়েবলটি আরম্ভের সমাপ্তির পরে ইনিশিয়াল হিসাবে বিবেচিত হয়"। অলস সিঙ্গলটন নির্মাণ বাস্তবায়নের জন্য এই সূচনাটি প্রথম ব্যবহারটি খুব সহজ।
6502

3.7.4: "স্থিতিশীল স্টোরেজ সময়কাল সহ একটি ব্লক-স্কোপ সত্তার ধ্রুবক সূচনা (3.6.2), যদি প্রযোজ্য হয় তবে এর ব্লকটি প্রথমে প্রবেশের আগে সম্পাদনা করা হয় with যার সাথে অন্য ব্লক-স্কোপ ভেরিয়েবলগুলির প্রাথমিক সূচনা করার অনুমতি দেওয়া হয় is স্ট্যাটিক বা থ্রেড স্টোরেজ সময়কাল একই অবস্থার অধীনে যে কোনও প্রয়োগের স্থায়িত্বমূলকভাবে নাম স্পেসে স্ট্যাটিক বা থ্রেড স্টোরেজ সময়কাল (3.6.2) সহ একটি পরিবর্তনশীল সূচনা করার অনুমতি দেওয়া হয়। অন্যথায় এ জাতীয় পরিবর্তনশীল প্রথমবারের মতো নিয়ন্ত্রণ তার ঘোষণার মধ্য দিয়ে যায়; "
0xbadf00d

1
কৌতূহলীভাবে যথেষ্ট তবে: 1) ধ্রুবক আরম্ভের জন্য এটি অপ্রাসঙ্গিক আলোচনা হচ্ছে যদি কোনও স্থানীয় স্ট্যাটিক প্রথমবার ব্লকে প্রবেশের আগে আরম্ভ করা যায় (পরিবর্তনশীল কেবলমাত্র ব্লকের ভিতরে দৃশ্যমান হয় এবং ধ্রুবক আরম্ভের কোনও পার্শ্ব প্রতিক্রিয়া তৈরি করে না); ২) আপনার পোস্টে ধ্রুবক সূচনা সম্পর্কে কিছুই বলা হয় না; ৩) অবিচ্ছিন্ন প্রারম্ভিককরণের জন্য স্থানীয় স্ট্যাটিকসগুলি খুব MyClass& instance(){ static MyClass x("config.ini"); return x; }কার্যকর - একক থ্রেড ব্যবহারের জন্য একটি বৈধ পোর্টেবল বাস্তবায়ন ঠিক কারণ স্থানীয় স্ট্যাটিক্স আপনি যা বলছেন তা সত্ত্বেও কোনও গ্লোবালের মতো নয়।
6502
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.