কীভাবে সি ++ তে প্রাইভেট স্ট্যাটিক সদস্যদের সূচনা করবেন?


518

সি ++ এ কোনও প্রাইভেট, স্ট্যাটিক ডেটা সদস্যকে শুরু করার সেরা উপায় কী? আমি এটি আমার হেডার ফাইলটিতে চেষ্টা করেছি, তবে এটি আমাকে অদ্ভুত লিঙ্কারের ত্রুটি দেয়:

class foo
{
    private:
        static int i;
};

int foo::i = 0;

আমি অনুমান করছি এটি কারণ আমি ক্লাসের বাইরে থেকে কোনও প্রাইভেট সদস্যকে আরম্ভ করতে পারি না। তাহলে এটি করার সর্বোত্তম উপায় কী?


2
হাই জেসন আমি স্থিতিশীল সদস্যদের ডিফল্ট সূচনা সম্পর্কে কোনও মন্তব্য পাই নি (উদাহরণস্বরূপ অবিচ্ছেদ্য ব্যক্তিরা)। আসলে আপনাকে int foo লিখতে হবে: i যাতে লিঙ্কার এটি খুঁজে পেতে পারে তবে এটি স্বয়ংক্রিয়ভাবে 0 দিয়ে আরম্ভ হবে! এই লাইনটি যথেষ্ট হবে: int foo :: i; (এটি স্ট্যাটিক মেমোরিতে সংরক্ষিত সমস্ত সামগ্রীর জন্য বৈধ, লিঙ্কার স্ট্যাটিক অবজেক্টগুলির সূচনা করার দায়িত্বে রয়েছে))
নিকো

1
নীচের উত্তরগুলি কোনও টেম্পলেট শ্রেণির জন্য প্রযোজ্য নয়। তারা বলে: সূচনা ফাইলটি অবশ্যই সূত্রের ফাইলে যেতে হবে। একটি টেম্পলেট শ্রেণীর জন্য, এটি নাও সম্ভব, না প্রয়োজনীয়।
জোচিম ডাব্লু

7
সি ++ 17 স্ট্যাটিক ডাটা সদস্যদের (এমনকি অ পূর্ণসংখ্যা ধরনের জন্য) এর ইনলাইন আরম্ভের অনুমতি দেয়: inline static int x[] = {1, 2, 3};En.cppreferences.com/w/cpp/language/static#Static_data_ মেম্বারস
ভ্লাদিমির

উত্তর:


556

শ্রেণীর ঘোষণাপত্রটি হেডার ফাইলে থাকা উচিত (বা ভাগ না করা থাকলে উত্স ফাইলে)।
ফাইল: foo.h

class foo
{
    private:
        static int i;
};

তবে সূচনা ফাইলটিতে হওয়া উচিত।
ফাইল: foo.cpp

int foo::i = 0;

যদি সূচনাটি হেডার ফাইলে থাকে তবে প্রতিটি ফাইল যার মধ্যে শিরোনাম ফাইল অন্তর্ভুক্ত থাকে তার স্থির সদস্যের সংজ্ঞা থাকবে। সুতরাং লিঙ্ক ফেজ চলাকালীন আপনি লিংক ত্রুটি পাবেন কারণ ভেরিয়েবলটি শুরু করার কোডটি একাধিক উত্স ফাইলে সংজ্ঞায়িত করা হবে। প্রয়োজনীয়টির সূচনাটি static int iকোনও ফাংশনের বাইরে করা আবশ্যক।

নোট: ম্যাট কার্টিস: POINTS আউট সি ++ এর সরলীকরণ পারবেন যে উপরোক্ত যদি স্ট্যাটিক সদস্য পরিবর্তনশীল const int- এ ধরনের (যেমন int, bool, char)। তারপরে আপনি শিরোনাম ফাইলটিতে ক্লাস ঘোষণার ভিতরে সদস্য ভেরিয়েবলটি সরাসরি ঘোষণা এবং সূচনা করতে পারেন:

class foo
{
    private:
        static int const i = 42;
};

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

11
প্রকৃতপক্ষে শুধু পড নয়, এটিও একটি প্রকার টাইপ হতে হবে (ইনট, শর্ট, বুল, চর ...)
ম্যাট কার্টিস

9
মনে রাখবেন যে মানটি কীভাবে আরম্ভ করা হয় তা কেবলমাত্র একটি প্রশ্ন নয়: কনস্ট ইন্টিগ্রাল টাইপগুলি এরূপ সংজ্ঞায়িত হয়ে বাস্তবায়ন দ্বারা সংকলিত সময়ের ধ্রুবকগুলিতে রূপান্তরিত হতে পারে। এটি সর্বদা আপনি যা চান তা নয়, কারণ এটি বাইনারি নির্ভরতা বাড়ায়: ক্লায়েন্ট কোডটির মান পরিবর্তিত হলে পুনরায় সংশোধন করা দরকার।
স্টিভ জেসপ

5
@ মার্টিন: সংশোধন ও / পিওডি / ইন্টিগ্রাল টাইপ / এর পাশাপাশি, যদি ঠিকানাটি কখনও নেওয়া হয় তবে তার একটি সংজ্ঞাও হওয়া দরকার। আশ্চর্যজনক যেহেতু এটি শোনাতে পারে, ক্লাস সংজ্ঞায় ইনিশিয়ালাইজার সহ ঘোষণাটি কোনও সংজ্ঞা নয়। টেমপ্লেট করা const বাগ্ধারা ক্ষেত্রে যেখানে আপনি একটি হেডার ফাইলে সংজ্ঞার প্রয়োজন একটি কার্যসংক্রান্ত প্রদান করে। আরেকটি এবং সহজ workaround একটি ফাংশন যা একটি স্থানীয় স্ট্যাটিক ধ্রুবকের মান উত্পাদন করে। চিয়ার্স এবং এইচটি।,
চিয়ার্স এবং এইচটিএইচ। - Alf

3
আপনি একটি স্পেসিফিকেশন যোগ করতে পারেন যে int foo :: i = 0; কোনও ফাংশনের অভ্যন্তরে থাকা উচিত নয় (মূল ফাংশন সহ)। আমার মূল ফাংশনের শুরুতে আমার এটি ছিল এবং এটি এটি পছন্দ করে না।
qwerty9967

89

একটি চলক জন্য :

foo.h:

class foo
{
private:
    static int i;
};

foo.cpp:

int foo::i = 0;

এটি কারণ foo::iআপনার প্রোগ্রামে কেবলমাত্র একটি উদাহরণ থাকতে পারে । এটি extern int iএকটি শিরোনাম ফাইল এবং int iএকটি উত্স ফাইল মধ্যে সমতুল্য সাজানোর ।

একটি জন্য ধ্রুবক তুমি ক্লাসে ঘোষণা মান সোজা লাগাতে পারেন:

class foo
{
private:
    static int i;
    const static int a = 42;
};

2
এটি একটি বৈধ পয়েন্ট। আমি এটিও আমার ব্যাখ্যা যুক্ত করব। তবে এটি লক্ষ করা উচিত যে এটি কেবল পিওডির জন্য কাজ করে।
মার্টিন ইয়র্ক

যেহেতু, সি ++ ইন-ক্লাসে ঘোষণার সাথে কেবল ভাল হতে দেয় এবং অবিচ্ছেদ্য ধরণের কোনও সংজ্ঞা নয়। যেহেতু সি ++ 98 নিজেই বা সি ++ 03 বা কখন? দয়া করে খাঁটি লিঙ্কগুলি ভাগ করুন। সি ++ স্ট্যান্ডার্ড শব্দের সংকলকগুলির সাথে সিঙ্ক হয় না। তারা উল্লেখ করে যে সদস্যটি তারা ব্যবহার করা থাকলে এখনও সংজ্ঞায়িত হবে। সুতরাং, আমার অবশ্য সি ++ স্ট্যান্ডার্ড
কোটিংয়ের দরকার নেই

1
আমি অবাক হই কেন কেন এখানে privateভ্যারিয়েবলগুলি ক্লাসের বাইরে আরম্ভ করা যেতে পারে, এটি স্থিতিশীল ভেরিয়েবলগুলির জন্যও করা যেতে পারে।
কৃষ্ণা ওজা

আপনি ব্যাখ্যা খুঁজে পেয়েছেন? @ কৃষ্ণ_উজা
nn0p

@ nn0p এখনও হয় নি, তবে বাইরে স্থিতিশীল বেসরকারী ভেরিয়েবল সূচনা সিপ্পিতে Classকোনও অর্থ দেয় না।
কৃষ্ণা ওজা

41

যেহেতু সি ++ 17, স্থির সদস্যদের সাথে শিরোনামে সংজ্ঞায়িত করা যেতে পারে ইনডলাইন কীওয়ার্ড ।

http://en.cppreference.com/w/cpp/language/static

"একটি স্ট্যাটিক ডেটা সদস্যকে ইনলাইন হিসাবে ঘোষণা করা যেতে পারে An একটি ইনলাইন স্ট্যাটিক ডেটা সদস্যকে শ্রেণীর সংজ্ঞায় সংজ্ঞায়িত করা যায় এবং কোনও ডিফল্ট সদস্য ইনিশিয়ালাইজার নির্দিষ্ট করতে পারে It এটির শ্রেণির সংজ্ঞা নেই:"

struct X
{
    inline static int n = 1;
};

1
সি ++ 17 এর পরে এটি সম্ভব, যা বর্তমানে নতুন স্ট্যান্ডার্ড হওয়ার প্রগতিতে রয়েছে।
গ্রেবু

31

এই প্রশ্নের ভবিষ্যতের দর্শকদের জন্য, আমি এটি উল্লেখ করতে চাই যে বানর0506 কী পরামর্শ দিচ্ছে তা আপনার এড়ানো উচিত ।

শিরোনামের ফাইলগুলি ঘোষণার জন্য।

শিরোলেখ ফাইলগুলি প্রতিটি .cppফাইলের জন্য একবার সংকলিত হয় যা প্রত্যক্ষ বা পরোক্ষভাবে #includesসেগুলি হয় এবং কোনও ফাংশনের বাইরের কোড প্রোগ্রামের সূচনাতে চালানো হয়, তার আগেmain()

foo::i = VALUE;হেডারে রেখে , প্রতিটি ফাইলের জন্য foo:iমান VALUE(যা কিছু হোক) নির্ধারিত হবে .cppএবং এই অ্যাসাইনমেন্টগুলি অনির্দিষ্ট আদেশে হবে (লিঙ্কারের দ্বারা নির্ধারিত) আগেmain() চালনার ।

#define VALUEআমাদের একের মধ্যে যদি আমরা আলাদা নম্বর হতে পারি তবে কী হবে.cpp ফাইলগুলির ? এটি জরিমানা সংকলন করবে এবং আমরা প্রোগ্রামটি চালা না করা পর্যন্ত কোনটি জিতবে তা জানার উপায় নেই।

কখনও কখনও মৃত্যুদন্ড কার্যকর করা কোডটিকে একই শিরোনামে রাখবেন না #includea.cpp ফাইল।

প্রহরীদের অন্তর্ভুক্ত করুন (যা আমি সর্বদা ব্যবহার করা উচিত বলে আপনাকে সম্মতি জানায়) আপনাকে আলাদা কিছু থেকে সুরক্ষা দেয়: একই ফাইলের #includeএকক .cppফাইল সংকলনের সময় পরোক্ষভাবে একাধিকবার ডি করা হচ্ছে


2
আপনি অবশ্যই এই বিষয়ে সঠিক, ক্লাস টেম্পলেটটির ক্ষেত্রে ব্যতীত (যা সম্পর্কে জিজ্ঞাসা করা হয়নি, তবে আমি অনেক কিছু নিয়ে কাজ করব)। সুতরাং যদি শ্রেণিটি সম্পূর্ণরূপে সংজ্ঞায়িত হয় এবং শ্রেণি টেম্পলেট নয়, তবে এই স্থিতিশীল সদস্যদের একটি পৃথক সিপিপি ফাইলে রাখুন, তবে শ্রেণি টেম্পলেটগুলির জন্য সংজ্ঞাটি একই অনুবাদ ইউনিটে থাকতে হবে (যেমন, শিরোনাম ফাইল)।
monkey0506

@ monkey_05_06: টেম্প্লেটেড কোডে স্থির সদস্য এড়ানোর পক্ষে এটি কেবল একটি যুক্তি বলে মনে হচ্ছে: আপনি ইতিমধ্যে ক্লাসের প্রতিটি ইনস্ট্যান্টেশনের জন্য একটি স্থির সদস্যের সাথে শেষ করেছেন। সমস্যাটি সম্ভবত একাধিক সিপিপি ফাইলগুলিতে শিরোনাম সংকলন করে আরও খারাপ হয়েছে ... আপনি বিরোধী সংজ্ঞাগুলির একটি ভেলা পেতে পারেন।
জোশুয়া ক্লেটন

publib.boulder.ibm.com/infocenter/macxhelp/v6v81/… এই লিঙ্কটিতে মূল ফাংশনটি ইনস্ট্যান্টিয়েট করা স্থির টেমপ্লেট সদস্যদের চিত্রিত করা হয়েছে, যা ক্লিনার, যদি কিছুটা বোঝা হয়।
জোশুয়া ক্লেটন

1
আপনার যুক্তি সত্যিই বিশাল প্রসারিত। প্রথমে আপনি # ভ্যালু নির্ধারণ করতে পারবেন না কারণ ম্যাক্রো নামটি একটি বৈধ শনাক্তকারী হতে পারে। এমনকি আপনি যদি করতে পারেন - কে এটা করবে? শিরোনামের ফাইলগুলি ঘোষণার জন্য -? সিমন .. কেবলমাত্র এমন ক্ষেত্রে যেখানে আপনার শিরোনামে মান স্থাপন করা এড়ানো উচিত অদ্ভুত-ব্যবহৃত লড়াই করা। এবং যখনই আপনাকে মান পরিবর্তন করার দরকার হয় তখন মানটি শিরোনামে রাখলে অপ্রয়োজনীয় পুনঃসংশোধন হতে পারে।
আলেকসান্দার ফুলার

20

একটি মাইক্রোসফ্ট সংকলক [1] দিয়ে স্ট্যাটিক ভেরিয়েবলগুলি যা intপছন্দসই নয় এটি একটি হেডার ফাইলে সংজ্ঞায়িত করা যায় তবে ক্লাস ঘোষণার বাইরে মাইক্রোসফ্ট নির্দিষ্ট ব্যবহার করে __declspec(selectany)

class A
{
    static B b;
}

__declspec(selectany) A::b;

নোট করুন যে আমি বলছি না এটি ভাল, আমি কেবল বলি এটি করা যায়।

[1] আজকাল, এমএসসি সমর্থনের চেয়ে বেশি সংকলক __declspec(selectany)- কমপক্ষে জিসিসি এবং ঝনঝন। আরও বেশি হতে পারে।


17
int foo::i = 0; 

পরিবর্তনশীল সূচনা করার জন্য সঠিক বাক্য গঠন, তবে এটি অবশ্যই শিরোনামের পরিবর্তে উত্স ফাইল (.cpp) এ যেতে হবে।

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


12

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

#ifndef FOO_H
#define FOO_H
#include "bar.h"

class foo
{
private:
    static bar i;
};

bar foo::i = VALUE;
#endif

আমি এর জন্য পৃথক সিপিপি ফাইল ব্যবহার করার দরকার নেই see অবশ্যই, আপনি পারবেন তবে আপনার কারন করার কোনও প্রযুক্তিগত কারণ নেই।


21
# অন্তর্ভুক্ত রক্ষীরা কেবল অনুবাদ ইউনিটে একাধিক সংজ্ঞা প্রতিরোধ করে।
পল ফুলটজ II

3
ভাল স্টাইল সম্পর্কিত: আপনার সমাপ্তি সম্পর্কে মন্তব্যটি যুক্ত করা উচিত:#endif // FOO_H
রিগা

9
এটি কেবলমাত্র যদি আপনার কেবলমাত্র একটি কম্পাইল ইউনিট থাকে যাতে foo.h. অন্তর্ভুক্ত থাকে তা কাজ করে যদি দুটি বা ততোধিক সিপিসি foo.h অন্তর্ভুক্ত করে, যা একটি সাধারণ পরিস্থিতি, প্রতিটি সিপিসি একই স্থিতিশীল ভেরিয়েবল ঘোষণা করবে যাতে লিঙ্কার multiple foo :: i 'এর একাধিক সংজ্ঞা দিয়ে অভিযোগ করবে যদি না আপনি ফাইলগুলির সাথে প্যাকেজ সংকলন ব্যবহার করেন (সংকলন) কেবলমাত্র একটি ফাইল যা সমস্ত সিপিএস অন্তর্ভুক্ত করে)। তবে প্যাকেজ সংকলন দুর্দান্ত হলেও সমস্যার সমাধানটি সিপিপিতে ঘোষণা করা (int foo :: i = 0;)!
আলেজাদ্রো জালাবার্ডার

1
বা কেবল ব্যবহার করুন#pragma once
টম্ব্রে

12

আপনি যদি কিছু যৌগিক প্রকার (ফে স্ট্রিং) শুরু করতে চান তবে আপনি এর মতো কিছু করতে পারেন:

class SomeClass {
  static std::list<string> _list;

  public:
    static const std::list<string>& getList() {
      struct Initializer {
         Initializer() {
           // Here you may want to put mutex
           _list.push_back("FIRST");
           _list.push_back("SECOND");
           ....
         }
      }
      static Initializer ListInitializationGuard;
      return _list;
    }
};

যেহেতু এটি ListInitializationGuardস্থিতিশীল পরিবর্তনশীল অভ্যন্তরীণ SomeClass::getList()পদ্ধতি হিসাবে এটি কেবল একবারই নির্মিত হবে, যার অর্থ কনস্ট্রাক্টরকে একবার বলা হয়। এটি initialize _listআপনার প্রয়োজনীয় মূল্যকে পরিবর্তনশীল করবে । পরবর্তী যে কোনও কল getListকেবল ইতোমধ্যে ইনিশিয়াল করা _listঅবজেক্টটি ফিরিয়ে দেবে ।

অবশ্যই আপনাকে _listকলিং getList()পদ্ধতিতে সর্বদা অবজেক্ট অ্যাক্সেস করতে হবে ।


1
এখানে প্রতি সদস্য বস্তুর এক পদ্ধতি তৈরি প্রয়োজন হয় না এই বাগ্ধারা একটি সংস্করণ হল: stackoverflow.com/a/48337288/895245
সিরো Santilli郝海东冠状病六四事件法轮功

9

সি ++ 11 স্ট্যাটিক কনস্ট্রাক্টর প্যাটার্ন যা একাধিক অবজেক্টের জন্য কাজ করে

একটি আইডিয়োম এখানে প্রস্তাবিত হয়েছিল: https://stackoverflow.com/a/27088552/895245 তবে এখানে একটি ক্লিনার সংস্করণ যায় যা সদস্য হিসাবে নতুন পদ্ধতি তৈরি করার প্রয়োজন হয় না।

main.cpp

#include <cassert>
#include <vector>

// Normally on the .hpp file.
class MyClass {
public:
    static std::vector<int> v, v2;
    static struct StaticConstructor {
        StaticConstructor() {
            v.push_back(1);
            v.push_back(2);
            v2.push_back(3);
            v2.push_back(4);
        }
    } _staticConstructor;
};

// Normally on the .cpp file.
std::vector<int> MyClass::v;
std::vector<int> MyClass::v2;
// Must come after every static member.
MyClass::StaticConstructor MyClass::_staticConstructor;

int main() {
    assert(MyClass::v[0] == 1);
    assert(MyClass::v[1] == 2);
    assert(MyClass::v2[0] == 3);
    assert(MyClass::v2[1] == 4);
}

গিটহাব উজানের দিকে

সংকলন এবং চালান:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out

আরও দেখুন: সি ++ এ স্ট্যাটিক কনস্ট্রাক্টর? আমার ব্যক্তিগত স্ট্যাটিক অবজেক্টগুলি শুরু করতে হবে initial

উবুন্টু 19.04 এ পরীক্ষিত।

সি ++ 17 ইনলাইন ভেরিয়েবল

এখানে উল্লেখ করা হয়েছে: https://stackoverflow.com/a/45062055/895245 তবে এটি আরও পরিষ্কার করার জন্য এখানে একটি বহুনির্বাচী চালানো উদাহরণ: ইনলাইন ভেরিয়েবলগুলি কীভাবে কাজ করে?


5

আপনি যদি শিরোনাম প্রহরী ব্যবহার করেন তবে আপনি হেডার ফাইলটিতে অ্যাসাইনমেন্টটি অন্তর্ভুক্ত করতে পারেন। আমি এই কৌশলটি আমার তৈরি সি ++ লাইব্রেরির জন্য ব্যবহার করেছি। একই ফলাফল অর্জনের আরেকটি উপায় হ'ল স্থির পদ্ধতি ব্যবহার করা। উদাহরণ স্বরূপ...

class Foo
   {
   public:
     int GetMyStatic() const
     {
       return *MyStatic();
     }

   private:
     static int* MyStatic()
     {
       static int mStatic = 0;
       return &mStatic;
     }
   }

উপরের কোডটিতে সিপিপি / উত্স ফাইলের প্রয়োজন নেই বলে "বোনাস" রয়েছে। আবার, আমি আমার সি ++ লাইব্রেরির জন্য একটি পদ্ধতি ব্যবহার করি।


4

আমি কার্লের ধারণাটি অনুসরণ করি। আমি এটি পছন্দ করি এবং এখন আমি এটিও ব্যবহার করি। আমি কিছুটা স্বরলিপি পরিবর্তন করেছি এবং কিছু কার্যকারিতা যুক্ত করেছি

#include <stdio.h>

class Foo
{
   public:

     int   GetMyStaticValue () const {  return MyStatic();  }
     int & GetMyStaticVar ()         {  return MyStatic();  }
     static bool isMyStatic (int & num) {  return & num == & MyStatic(); }

   private:

      static int & MyStatic ()
      {
         static int mStatic = 7;
         return mStatic;
      }
};

int main (int, char **)
{
   Foo obj;

   printf ("mystatic value %d\n", obj.GetMyStaticValue());
   obj.GetMyStaticVar () = 3;
   printf ("mystatic value %d\n", obj.GetMyStaticValue());

   int valMyS = obj.GetMyStaticVar ();
   int & iPtr1 = obj.GetMyStaticVar ();
   int & iPtr2 = valMyS;

   printf ("is my static %d %d\n", Foo::isMyStatic(iPtr1), Foo::isMyStatic(iPtr2));
}

এই ফলাফল

mystatic value 7
mystatic value 3
is my static 1 0

3

প্রাইভেটস্ট্যাটিক সিপিপি ফাইলেও কাজ করছে:

#include <iostream>

using namespace std;

class A
{
private:
  static int v;
};

int A::v = 10; // possible initializing

int main()
{
A a;
//cout << A::v << endl; // no access because of private scope
return 0;
}

// g++ privateStatic.cpp -o privateStatic && ./privateStatic

3

একটি set_default()পদ্ধতি সম্পর্কে কি ?

class foo
{
    public:
        static void set_default(int);
    private:
        static int i;
};

void foo::set_default(int x) {
    i = x;
}

আমাদের কেবল set_default(int x)পদ্ধতিটি ব্যবহার staticকরতে হবে এবং আমাদের ভেরিয়েবলটি আরম্ভ করা হবে।

এটি বাকী মন্তব্যের সাথে দ্বিমত পোষণ করবে না, আসলে এটি বৈশ্বিক স্কোপে পরিবর্তনশীল সূচনা করার একই নীতি অনুসরণ করে, তবে এই পদ্ধতিটি ব্যবহার করে আমরা সংজ্ঞাটি না দিয়ে এটিকে সুস্পষ্ট (এবং দেখতে সহজ) বুঝতে পারি সেখানে ঝুলন্ত পরিবর্তনশীল।


3

আপনি যে লিঙ্কারের সমস্যাটির মুখোমুখি হয়েছিলেন সম্ভবত এটির কারণে হয়েছে:

  • শিরোলেখ ফাইলটিতে শ্রেণি এবং স্থির সদস্য উভয় সংজ্ঞা সরবরাহ করা,
  • দুই বা ততোধিক উত্স ফাইলে এই শিরোনামটি অন্তর্ভুক্ত।

যারা সি ++ দিয়ে শুরু করেন তাদের ক্ষেত্রে এটি একটি সাধারণ সমস্যা। স্ট্যাটিক ক্লাসের সদস্যকে একক অনুবাদ ইউনিটে অর্থাৎ একক উত্স ফাইলে সূচনা করতে হবে।

দুর্ভাগ্যক্রমে, স্থির শ্রেণীর সদস্যকে অবশ্যই শ্রেণীর বডির বাইরে আরম্ভ করতে হবে। এটি শিরোনাম-কেবল কোড লিখতে জটিল করে তোলে এবং তাই আমি বেশ ভিন্ন পদ্ধতির ব্যবহার করছি। আপনি স্থির বা অ-স্থিতিশীল শ্রেণীর ফাংশনের মাধ্যমে আপনার স্ট্যাটিক অবজেক্টটি সরবরাহ করতে পারেন উদাহরণস্বরূপ:

class Foo
{
    // int& getObjectInstance() const {
    static int& getObjectInstance() {
        static int object;
        return object;
    }

    void func() {
        int &object = getValueInstance();
        object += 5;
    }
};

1
সি ++ যতদূর যায় আমি এখনও সম্পূর্ণ n00b, তবে এটি আমার কাছে উজ্জ্বল দেখাচ্ছে, আপনাকে অনেক ধন্যবাদ! আমি বিনামূল্যে সিঙ্গলটন অবজেক্টের নিখুঁত জীবনচক্র পরিচালনা পেতে পারি management
রাফায়েল কিটওভার

2

ধ্রুবককে সংজ্ঞায়িত করার একটি "পুরাতন-স্কুল" উপায় হ'ল তাদের দ্বারা প্রতিস্থাপন enum:

class foo
{
    private:
        enum {i = 0}; // default type = int
        enum: int64_t {HUGE = 1000000000000}; // may specify another type
};

এইভাবে কোনও সংজ্ঞা দেওয়ার প্রয়োজন হয় না এবং ধ্রুবক লভ্যু তৈরি করা এড়ানো যায় না, যা আপনাকে কিছু মাথা ব্যথা বাঁচাতে পারে, যেমন আপনি যখন দুর্ঘটনাক্রমে এটি ওডিআর ব্যবহার করেন।


1

আমি যখন প্রথমবার মুখোমুখি হলাম তখন আমি আমার কাছে কিছুটা অদ্ভুত কিছু উল্লেখ করতে চেয়েছিলাম।

আমার একটি টেমপ্লেট ক্লাসে একটি প্রাইভেট স্ট্যাটিক ডেটা সদস্যকে শুরু করতে হবে।

.h বা .hpp এ কোনও টেম্পলেট শ্রেণীর স্ট্যাটিক ডেটা সদস্যকে সূচনা করার জন্য এমন কিছু দেখাচ্ছে:

template<typename T>
Type ClassName<T>::dataMemberName = initialValue;

0

এটি কি আপনার উদ্দেশ্যটি পরিবেশন করে?

//header file

struct MyStruct {
public:
    const std::unordered_map<std::string, uint32_t> str_to_int{
        { "a", 1 },
        { "b", 2 },
        ...
        { "z", 26 }
    };
    const std::unordered_map<int , std::string> int_to_str{
        { 1, "a" },
        { 2, "b" },
        ...
        { 26, "z" }
    };
    std::string some_string = "justanotherstring";  
    uint32_t some_int = 42;

    static MyStruct & Singleton() {
        static MyStruct instance;
        return instance;
    }
private:
    MyStruct() {};
};

//Usage in cpp file
int main(){
    std::cout<<MyStruct::Singleton().some_string<<std::endl;
    std::cout<<MyStruct::Singleton().some_int<<std::endl;
    return 0;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.