आप C ++ में एक स्थिर वर्ग कैसे बनाते हैं?


263

आप C ++ में एक स्थिर वर्ग कैसे बनाते हैं? मुझे ऐसा कुछ करने में सक्षम होना चाहिए:

cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;

मान लिया मैंने BitParserकक्षा बनाई । BitParserवर्ग की परिभाषा क्या दिखेगी?


198
हां। पुराने दिनों में वापस, हमने सिर्फ एक "फ़ंक्शन" कहा। आप आज बच्चों को अपने पागल "नामस्थान" के साथ। अरे, मेरे लॉन से उतरो! <> मुट्ठी हिलाता है
१०:४१

7
@Vagrant एक नाम स्थान के अंदर एक फ़ंक्शन अभी भी एक फ़ंक्शन है। एक फ़ंक्शन जो किसी वर्ग से संबंधित होता है उसे एक विधि कहा जाता है। यदि यह एक स्थिर विधि है, तो आप इसे उसी तरह से लागू करते हैं जैसे कि यह किसी नामस्थान के अंदर एक फ़ंक्शन था।

48
5 साल बाद और अब मैं @Vagrant के साथ साइडिंग कर रहा हूं। क्या मूर्खतापूर्ण सवाल है!
andrewrk

16
9 साल बाद और अब मेरी अपनी प्रोग्रामिंग भाषा है जिसमें कक्षाएं भी नहीं हैं: ziglang.org
andrewrk

1
IMO कंटेनर जैसी कक्षाएं (केवल स्थिर विधियाँ होने) कुछ मामलों में उपयोगी होती हैं।
आरसीई

जवाबों:


272

यदि आप "स्थिर" कीवर्ड को किसी वर्ग में लागू करने का एक तरीका खोज रहे हैं, जैसे आप C # उदाहरण के लिए कर सकते हैं, तो आप प्रबंधित C ++ का उपयोग किए बिना नहीं कर पाएंगे।

लेकिन आपके नमूने की झलक, आपको बस अपने BitParser ऑब्जेक्ट पर एक सार्वजनिक स्थैतिक विधि बनाने की आवश्यकता है। इस तरह:

BitParser.h

class BitParser
{
 public:
  static bool getBitAt(int buffer, int bitIndex);

  // ...lots of great stuff

 private:
  // Disallow creating an instance of this object
  BitParser() {}
};

BitParser.cpp

bool BitParser::getBitAt(int buffer, int bitIndex)
{
  bool isBitSet = false;
  // .. determine if bit is set
  return isBitSet;
}

आप इस कोड का उपयोग उसी तरीके से कर सकते हैं, जिस तरह से आप अपने उदाहरण कोड में करते हैं।

उम्मीद है की वो मदद करदे! चीयर्स।


2
OJ, आपके पास एक सिंटैक्स त्रुटि है । स्थैतिक खोजशब्द का उपयोग केवल कक्षा परिभाषा में किया जाना चाहिए, न कि विधि परिभाषा में।
andrewrk

90
इस दृष्टिकोण में अपना इरादा स्पष्ट करने के लिए आप निजी रूप से एक कंस्ट्रक्टर का उपयोग कर सकते हैं। private: BitParser() {}यह किसी को भी उदाहरण बनाने से रोकेगा।
दानविल

7
जब आप राज्य साझा करते हैं तो @MoatazElmasry थ्रेड सुरक्षा एक समस्या है। उपरोक्त कार्यान्वयन में कोई राज्य साझा नहीं है, इसलिए थ्रेड सुरक्षा के साथ कोई समस्या नहीं हो सकती है ... जब तक कि आप उन कार्यों के अंदर स्टेटिक्स का उपयोग करने के लिए पर्याप्त बेवकूफ नहीं हैं । तो हां, ऊपर दिया गया कोड थ्रेड सुरक्षित है, बस अपने कार्यों से लगातार स्थिति बनाए रखें और आप अच्छे हैं।
ओ जे।

@MoatazElmasry गलत है। दो सूत्र एक स्थिर फ़ंक्शन में गैर-स्थिर स्थानीय चर को संशोधित नहीं कर सकते हैं।
ओ जे।

12
यदि C ++ 11, मैं तर्क देता BitParser() = delete;हूं कि कंस्ट्रक्टर को हटाने के इरादे को ठीक से बताना बेहतर है (न कि इसे केवल छिपाना private)।
फीनिक्स

247

मैट प्राइस के समाधान पर विचार करें ।

  1. C ++ में, "स्थिर वर्ग" का कोई अर्थ नहीं है। निकटतम चीज केवल स्थिर विधियों और सदस्यों के साथ एक वर्ग है।
  2. स्थैतिक तरीकों का उपयोग केवल आपको सीमित करेगा।

, सी ++ अर्थ विज्ञान में व्यक्त अपने कार्य डाल करने के लिए (के लिए यह क्या आप चाहते हैं, है एक नाम स्थान में एक समारोह)।

2011-11-11 को संपादित करें

C ++ में कोई "स्थिर वर्ग" नहीं है। निकटतम अवधारणा केवल स्थिर विधियों वाला एक वर्ग होगा। उदाहरण के लिए:

// header
class MyClass
{
   public :
      static void myMethod() ;
} ;

// source
void MyClass::myMethod()
{
   // etc.
}

लेकिन आपको याद रखना चाहिए कि जावा जैसी तरह की भाषाओं में "स्टैटिक क्लासेस" हैक होती हैं (जैसे C #) जो गैर-सदस्य फ़ंक्शंस करने में असमर्थ हैं, इसलिए उन्हें स्टैटिक विधियों के रूप में कक्षाओं के अंदर ले जाने के बजाय है।

C ++ में, जो आप वास्तव में चाहते हैं वह एक गैर-सदस्यीय फ़ंक्शन है जिसे आप एक नाम स्थान में घोषित करेंगे:

// header
namespace MyNamespace
{
   void myMethod() ;
}

// source
namespace MyNamespace
{
   void myMethod()
   {
      // etc.
   }
}

ऐसा क्यों है?

C ++ में, नाम "जावा स्टैटिक मेथड" पैटर्न के लिए कक्षाओं की तुलना में अधिक शक्तिशाली है, क्योंकि:

  • स्थिर विधियों में कक्षाओं के निजी प्रतीकों तक पहुंच है
  • निजी स्थिर विधियाँ अभी भी सभी के लिए (यदि दुर्गम हैं) दिखाई दे रही हैं, जो कुछ हद तक एनकैप्सुलेशन को तोड़ती हैं
  • स्थिर तरीकों को आगे घोषित नहीं किया जा सकता है
  • लाइब्रेरी हेडर को संशोधित किए बिना स्थिर तरीकों को वर्ग उपयोगकर्ता द्वारा अधिभारित नहीं किया जा सकता है
  • ऐसा कुछ भी नहीं है जो एक स्थिर विधि द्वारा किया जा सकता है जो एक ही नामस्थान में (संभवतः मित्र) गैर-सदस्य फ़ंक्शन से बेहतर नहीं किया जा सकता है
  • नामस्थानों के अपने शब्दार्थ हैं (उन्हें जोड़ा जा सकता है, वे गुमनाम हो सकते हैं, आदि)
  • आदि।

निष्कर्ष: C ++ में जावा / सी # पैटर्न को कॉपी / पेस्ट न करें। जावा / सी # में, पैटर्न अनिवार्य है। लेकिन C ++ में, यह खराब शैली है।

2010-06-10 संपादित करें

स्थैतिक विधि के पक्ष में एक तर्क था क्योंकि कभी-कभी, किसी को स्थिर निजी सदस्य चर का उपयोग करने की आवश्यकता होती है।

मैं कुछ हद तक असहमत हूं, जैसा कि नीचे दिखाया गया है:

"स्थैतिक निजी सदस्य" समाधान

// HPP

class Foo
{
   public :
      void barA() ;
   private :
      void barB() ;
      static std::string myGlobal ;
} ;

सबसे पहले, myGlobal को myGlobal कहा जाता है क्योंकि यह अभी भी एक वैश्विक निजी चर है। CPP स्रोत पर एक नज़र स्पष्ट करेगी कि:

// CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP

void Foo::barA()
{
   // I can access Foo::myGlobal
}

void Foo::barB()
{
   // I can access Foo::myGlobal, too
}

void barC()
{
   // I CAN'T access Foo::myGlobal !!!
}

पहली नजर में, तथ्य यह है कि नि: शुल्क फ़ंक्शन बारसी फू का उपयोग नहीं कर सकता है :: myGlobal एक एनकैप्सुलेशन दृष्टिकोण से एक अच्छी बात है ... यह अच्छा है क्योंकि एचपीपी को देखने वाला कोई भी व्यक्ति (जब तक कि तोड़फोड़ का सहारा नहीं ले सकता) तक पहुंच नहीं सकता है फू :: myGlobal।

लेकिन यदि आप इसे करीब से देखते हैं, तो आप पाएंगे कि यह एक भारी गलती है: न केवल आपके निजी चर को अभी भी एचपीपी में घोषित किया जाना चाहिए (और इसलिए, निजी होने के बावजूद सभी दुनिया के लिए दृश्यमान है), लेकिन आपको घोषित करना चाहिए एक ही एचपीपी में सभी (सभी के रूप में) कार्य जो इसे एक्सेस करने के लिए अधिकृत होंगे !!!

इसलिए एक निजी स्थिर सदस्य का उपयोग करना आपकी त्वचा पर टैटू किए गए प्रेमियों की सूची के साथ नग्न होकर बाहर घूमने जैसा है: कोई भी छूने के लिए अधिकृत नहीं है, लेकिन हर कोई झांकने में सक्षम है। और बोनस: हर किसी के पास आपके निजी के साथ खेलने के लिए अधिकृत लोगों के नाम हो सकते हैं।

private वास्तव में ...: -डॉ

"अनाम नामस्थान" समाधान

बेनामी नेमस्पेस में निजी तौर पर चीजों को निजी बनाने का फायदा होगा।

सबसे पहले, एचपीपी हेडर

// HPP

namespace Foo
{
   void barA() ;
}

बस यह सुनिश्चित करने के लिए कि आपने टिप्पणी की है: न तो बारबी की कोई बेकार घोषणा है और न ही मायग्लोबल। जिसका अर्थ है कि हेडर को पढ़ने वाला कोई नहीं जानता कि बार के पीछे क्या छिपा है।

फिर, CPP:

// CPP
namespace Foo
{
   namespace
   {
      std::string myGlobal ;

      void Foo::barB()
      {
         // I can access Foo::myGlobal
      }
   }

   void barA()
   {
      // I can access myGlobal, too
   }
}

void barC()
{
   // I STILL CAN'T access myGlobal !!!
}

जैसा कि आप देख सकते हैं, तथाकथित "स्थिर वर्ग" घोषणा की तरह, fooA और fooB अभी भी myGlobal तक पहुंचने में सक्षम हैं। लेकिन कोई और नहीं कर सकता। और इस सीपीपी के बाहर कोई और नहीं जानता कि fooB और myGlobal भी मौजूद है!

"स्टैटिक क्लास" के विपरीत, उसकी पता पुस्तिका में उसकी त्वचा पर टैटू वाली "अनाम" नाम की पुड़िया पूरी तरह से चढ़ी हुई है , जो काफी अच्छी तरह से AFAIK से घिरा हुआ लगता है।

क्या यह वास्तव में मायने रखता है?

जब तक आपके कोड के उपयोगकर्ता सबोटर्स नहीं होते हैं (मैं आपको एक अभ्यास के रूप में बताता हूं, यह पता लगाएं कि एक सार्वजनिक वर्ग के निजी हिस्से तक पहुंच कैसे एक गंदा व्यवहार-अपरिभाषित हैक का उपयोग कर सकता है ...), क्या privateहै private, भले ही वह क्या हो privateएक हेडर में घोषित एक वर्ग के अनुभाग में दिखाई देता है ।

फिर भी, अगर आपको निजी सदस्य तक पहुंच के साथ एक और "निजी फ़ंक्शन" जोड़ने की आवश्यकता है, तो आपको अभी भी हेडर को संशोधित करके इसे पूरी दुनिया के लिए घोषित करना होगा, जो कि एक विरोधाभास है जहां तक ​​मेरा संबंध है: यदि मैं कार्यान्वयन को बदल देता हूं मेरा कोड (CPP भाग), तो इंटरफ़ेस (HPP भाग) को बदलना नहीं चाहिए। लियोनिदास का हवाला देते हुए: " यह उत्साह है! "

2014-09-20 संपादित करें

जब वर्ग स्थैतिक विधियाँ वास्तव में गैर-सदस्य कार्यों वाले नाम स्थान से बेहतर होती हैं?

जब आपको समूह में एक साथ कार्य करने की आवश्यकता हो और उस समूह को खाके पर फ़ीड करें:

namespace alpha
{
   void foo() ;
   void bar() ;
}

struct Beta
{
   static void foo() ;
   static void bar() ;
};

template <typename T>
struct Gamma
{
   void foobar()
   {
      T::foo() ;
      T::bar() ;
   }
};

Gamma<alpha> ga ; // compilation error
Gamma<Beta> gb ;  // ok
gb.foobar() ;     // ok !!!

क्योंकि, यदि कोई वर्ग एक टेम्पलेट पैरामीटर हो सकता है, तो एक नाम स्थान नहीं हो सकता है।


3
GCC -fno-access-control का समर्थन करता है, जिसका उपयोग अन्यथा निजी वर्ग के सदस्यों तक पहुँचने के लिए व्हाइटबॉक्स यूनिट परीक्षणों में किया जा सकता है। यही एकमात्र कारण है कि मैं कार्यान्वयन में एक अनाम / स्थिर वैश्विक के बजाय एक वर्ग के सदस्य का उपयोग करने को सही ठहराने के बारे में सोच सकता हूं।
टॉम

8
@ टोम: क्रॉस-प्लेटफ़ॉर्म समाधान #define private publicहेडर में निम्न कोड जोड़ना होगा ... ^ _ ^ ...
पियरसेबल

1
@Tom: वैसे भी, IMHO, यहां तक ​​कि यूनिट परीक्षण पर भी, "बहुत अधिक सामान दिखाने" की विपक्ष पेशेवरों को मात देता है। मुझे लगता है कि एक वैकल्पिक समाधान एक utilitiesनाम स्थान में आवश्यक मापदंडों (और अधिक नहीं) लेने वाले फ़ंक्शन में परीक्षण किए जाने के लिए कोड डालना होगा । इस तरह, इस फ़ंक्शन को यूनिट-परीक्षण किया जा सकता है, और अभी भी निजी सदस्यों तक कोई विशेष पहुंच नहीं है (जैसा कि उन्हें फ़ंक्शन कॉल में पैरामीटर के रूप में दिया गया है) ...
paercebal

@paercebal मैं आपके जहाज पर कूदने वाला हूं, लेकिन मेरे पास एक अंतिम आरक्षण है। यदि कोई आपकी छलांग लगाता है, तो namespaceक्या वे आपके लिए पहुँच प्राप्त नहीं करेंगे global, यद्यपि छिपे हुए, सदस्य? जाहिर है कि उन्हें अनुमान लगाना होगा, लेकिन जब तक आप जानबूझकर अपने कोड को नहीं मान रहे हैं, चर नाम अनुमान लगाने में बहुत आसान हैं।
ज़क

@Zak: वास्तव में, वे कर सकते हैं, लेकिन केवल CPP फ़ाइल में यह करने की कोशिश करके जहाँ myGlobal चर घोषित किया गया है। पहुंच की तुलना में बिंदु अधिक दृश्यता है। स्थिर वर्ग में, myGlobal चर निजी है, लेकिन फिर भी दिखाई देता है। यह उतना महत्वपूर्ण नहीं है जितना लगता है, लेकिन फिर भी, एक DLL में, एक प्रतीक दिखा रहा है जो निर्यात किए गए शीर्ष लेख में DLL के लिए निजी होना चाहिए, अजीब हो सकता है ... नाम स्थान में, MyGlobal केवल CPP फ़ाइल में मौजूद है (आप यहां तक ​​कि आगे जा सकते हैं और इसे स्थिर बना सकते हैं)। वह चर सार्वजनिक शीर्ष लेखों में दिखाई नहीं देता है।
22

63

आप एक नाम स्थान में एक नि: शुल्क फ़ंक्शन भी बना सकते हैं:

BitParser.h में

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex);
}

BitParser.cpp में

namespace BitParser
{
    bool getBitAt(int buffer, int bitIndex)
    {
        //get the bit :)
    }
}

सामान्य तौर पर यह कोड लिखने का पसंदीदा तरीका होगा। जब किसी वस्तु की आवश्यकता नहीं है तो कक्षा का उपयोग न करें।


1
कुछ मामलों में आप चाहते हैं कि डेटा इनकैप्सुलेशन हो, भले ही वर्ग ज्यादातर "स्थिर" हो। स्टेटिक प्राइवेट क्लास के सदस्य आपको यह देंगे। नेमस्पेस सदस्य हमेशा सार्वजनिक होते हैं और डेटा एनकैप्सुलेशन प्रदान नहीं कर सकते हैं।
टॉर्लिफ

यदि "सदस्य" संस्करण केवल .cpp फ़ाइल से घोषित और पहुँचा हुआ है, तो यह .h फ़ाइल में घोषित निजी संस्करण से अधिक निजी है। ऐसा नहीं है कि मैं इस तकनीक की सलाह देता हूं।
19uc में jmucchiello

3
@Torleif: आप गलत हैं। स्थिर निजी सदस्यों की तुलना में नामस्थान बेहतर हैं। प्रदर्शन के लिए मेरा जवाब देखें।
पियरसबल

1
हाँ, लेकिन नाम स्थान में आपको स्थिर सदस्यों के साथ वर्ग के विपरीत, फंक्शन ऑर्डर रखना होगा, उदाहरण के लिए शून्य () (बी) (;} बी) () {} एक नेमस्पेस में त्रुटि उत्पन्न करेगा लेकिन क्लास में नहीं स्थिर सदस्य
Moataz Elmasry

13

यदि आप "स्थिर" कीवर्ड को क्लास में लागू करने का एक तरीका खोज रहे हैं, जैसे आप C # उदाहरण के लिए कर सकते हैं

स्टैटिक क्लासेस सिर्फ संकलक का हाथ होता है, जो आपको किसी भी उदाहरण के तरीके / चर लिखने से रोकता है।

यदि आप किसी सामान्य तरीके को बिना किसी उदाहरण के तरीके / चर के साथ लिखते हैं, तो यह एक ही बात है, और यही आप C ++ में करेंगे


शिकायत करने के लिए नहीं (विशेष रूप से आप पर), लेकिन कुछ संकलक हाथ से मुझे static200 बार लिखने या काटने / चिपकाने से रोकने के लिए एक अच्छी बात होगी।
डीवी

सहमत - लेकिन C # में एक स्थिर वर्ग ऐसा नहीं करता है। जब आप स्टेटिक को पेस्ट करना भूल जाते हैं तो यह संकलन करने में विफल रहता है :-)
ओरियन एडवर्ड्स

हाँ - पर्याप्त निष्पक्ष। मेरे मैक्रों दिखा रहे हैं। ईमानदारी से, अगर मैं कक्षा को स्थिर घोषित करता हूं, तो कंपाइलर को केवल एक त्रुटि फेंकनी चाहिए, अगर मैं इसे तुरंत करने की कोशिश करता हूं। नियम जिन्हें मुझे खुद को दोहराने की आवश्यकता है वे अप्रिय हैं और क्रांति आने पर दीवार के खिलाफ पहला होना चाहिए।
डी एनवी

11

C ++ में आप एक क्लास (स्टैटिक क्लास नहीं) का स्टैटिक फंक्शन बनाना चाहते हैं।

class BitParser {
public:
  ...
  static ... getBitAt(...) {
  }
};

तब आपको बिटपर्सर :: getBitAt () का उपयोग किए बिना फ़ंक्शन को कॉल करने में सक्षम होना चाहिए, जो किसी ऑब्जेक्ट को तुरंत बताए बिना मैं वांछित परिणाम है।


11

क्या मैं कुछ लिख सकता हूँ static class?

नहीं , C ++ 11 N3337 मानक ड्राफ्ट अनुलग्नक C 7.1.1 के अनुसार:

परिवर्तन: C ++ में, स्थिर या बाहरी विनिर्देशक केवल वस्तुओं या कार्यों के नाम पर ही लागू किए जा सकते हैं। इन घोषणाओं के साथ प्रकारों का उपयोग करना C ++ में अवैध है। सी में, इन घोषणाओं को नजरअंदाज कर दिया जाता है जब प्रकार की घोषणाओं पर उपयोग किया जाता है। उदाहरण:

static struct S {    // valid C, invalid in C++
  int i;
};

Rationale: भंडारण वर्ग के विनिर्माताओं के पास किसी प्रकार से जुड़े होने का कोई अर्थ नहीं है। C ++ में, क्लास मेंबर्स को स्टैटिक स्टोरेज क्लास स्पेसियर के साथ घोषित किया जा सकता है। प्रकार की घोषणाओं पर भंडारण वर्ग निर्दिष्ट करना उपयोगकर्ताओं के लिए भ्रमित करने वाले कोड को प्रस्तुत कर सकता है।

और जैसे struct, classएक प्रकार की घोषणा भी है।

एनेक्स ए में वाक्य रचना के पेड़ पर चलने से भी ऐसा ही किया जा सकता है।

यह ध्यान रखना दिलचस्प है कि static structसी में कानूनी था, लेकिन इसका कोई प्रभाव नहीं था: सी प्रोग्रामिंग में स्थिर संरचनाओं का उपयोग क्यों और कब करना है?


6

जैसा कि यहां बताया गया है, सी ++ में इसे प्राप्त करने का एक बेहतर तरीका नामस्थान का उपयोग हो सकता है। लेकिन चूंकि किसी ने भी finalयहां कीवर्ड का उल्लेख नहीं किया है, इसलिए मैं पोस्ट कर रहा हूं कि static classC # से एक सीधा समतुल्य C ++ 11 या बाद में कैसा दिखेगा:

class BitParser final
{
public:
  BitParser() = delete;

  static bool GetBitAt(int buffer, int pos);
};

bool BitParser::GetBitAt(int buffer, int pos)
{
  // your code
}

5

आपके पास C ++ में एक स्थिर वर्ग हो सकता है, जैसा कि पहले उल्लेख किया गया है, एक स्थिर वर्ग वह है जिसमें इसकी कोई भी वस्तु त्वरित नहीं है। C ++ में, यह कंस्ट्रक्टर / विध्वंसक को निजी घोषित करके प्राप्त किया जा सकता है। अंतिम परिणाम समान है।


आप जो सुझाव दे रहे हैं, वह एकल वर्ग बना सकता है, लेकिन यह एक स्थिर वर्ग जैसा नहीं है।
क्षिंकर

4

प्रबंधित C ++ में, स्थिर वर्ग वाक्यविन्यास है: -

public ref class BitParser abstract sealed
{
    public:
        static bool GetBitAt(...)
        {
            ...
        }
}

... देर आए दुरुस्त आए...


3

यह C ++ में करने के C # तरीके के समान है

C # file.cs में आप किसी सार्वजनिक फ़ंक्शन के अंदर निजी संस्करण रख सकते हैं। जब किसी अन्य फ़ाइल में आप फ़ंक्शन के साथ नेमस्पेस कॉल करके इसका उपयोग कर सकते हैं:

MyNamespace.Function(blah);

यहाँ C ++ में समान कैसे लागू करें:

SharedModule.h

class TheDataToBeHidden
{
  public:
    static int _var1;
    static int _var2;
};

namespace SharedData
{
  void SetError(const char *Message, const char *Title);
  void DisplayError(void);
}

SharedModule.cpp

//Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;


//Implement the namespace
namespace SharedData
{
  void SetError(const char *Message, const char *Title)
  {
    //blah using TheDataToBeHidden::_var1, etc
  }

  void DisplayError(void)
  {
    //blah
  }
}

OtherFile.h

#include "SharedModule.h"

OtherFile.cpp

//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();

2
लेकिन हर कोई TheDataToBeHidden के पास जा सकता है -> यह एक समाधान नहीं है
लड़के एल

3

अन्य प्रबंधित प्रोग्रामिंग भाषा के विपरीत, "स्थिर वर्ग" का C ++ में कोई अर्थ नहीं है। आप स्थैतिक सदस्य फ़ंक्शन का उपयोग कर सकते हैं।


0

एक मामला जहां नाम स्थान "स्थिर वर्गों" को प्राप्त करने के लिए इतना उपयोगी नहीं हो सकता है, जब इन वर्गों का उपयोग वंशानुक्रम पर रचना को प्राप्त करने के लिए किया जाता है। नाम स्थान वर्गों के मित्र नहीं हो सकते हैं और इसलिए किसी वर्ग के निजी सदस्यों तक नहीं पहुंच सकते हैं।

class Class {
 public:
  void foo() { Static::bar(*this); }    

 private:
  int member{0};
  friend class Static;
};    

class Static {
 public:
  template <typename T>
  static void bar(T& t) {
    t.member = 1;
  }
};

0

एक (कई में से) वैकल्पिक, लेकिन सबसे (मेरी राय में) सुरुचिपूर्ण (स्थैतिक व्यवहार का अनुकरण करने के लिए नामस्थान और निजी निर्माणकर्ताओं का उपयोग करने की तुलना में), C ++ में "वर्ग जो तात्कालिक नहीं हो सकता" व्यवहार को प्राप्त करने का तरीका होगा। privateपहुँच संशोधक के साथ एक डमी शुद्ध आभासी फ़ंक्शन की घोषणा करें ।

class Foo {
   public:
     static int someMethod(int someArg);

   private:
     virtual void __dummy() = 0;
};

यदि आप C ++ 11 का उपयोग कर रहे हैं, तो आप यह सुनिश्चित करने के लिए अतिरिक्त मील जा सकते हैं कि finalवर्ग की घोषणा में विशुद्ध रूप से (किसी स्थिर वर्ग के व्यवहार का अनुकरण करने के लिए) वर्ग की घोषणा में विनिर्देशक का उपयोग करके अन्य वर्गों को विरासत से प्रतिबंधित कर दिया जाए। ।

// C++11 ONLY
class Foo final {
   public:
     static int someMethod(int someArg);

   private:
      virtual void __dummy() = 0;
};

जैसा कि मूर्खतापूर्ण और अतार्किक लग सकता है, C ++ 11 एक "शुद्ध आभासी फ़ंक्शन जिसे ओवरराइड नहीं किया जा सकता है" की घोषणा की अनुमति देता है, जिसका उपयोग आप कक्षा finalको पूरी तरह से घोषित करने के साथ-साथ स्थैतिक व्यवहार को पूरी तरह से लागू कर सकते हैं क्योंकि यह परिणामी है। किसी भी तरह से अतिरंजित नहीं होने के लिए वर्ग और अंतर्निहित कार्य नहीं किया जाना चाहिए।

// C++11 ONLY
class Foo final {
   public:
     static int someMethod(int someArg);

   private:
     // Other private declarations

     virtual void __dummy() = 0 final;
}; // Foo now exhibits all the properties of a static class
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.