2011-01-10 16 views
48

संभव डुप्लिकेट:
What is the use of making constructor private in a class?निजी निर्माता

हम कहाँ निजी निर्माता की आवश्यकता है? हम निजी कन्स्ट्रक्टर वाले वर्ग को कैसे चालू कर सकते हैं?

+2

यह भी देखें http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class – StuartLC

+0

अच्छी तरह से देखा गया है, इस प्रश्न का स्वीकार्य उत्तर भी है सी ++ के लिए बेकार -> सी ++ में स्थिर कार्यों की कक्षा बनाने के लिए यह बुरा स्वाद है, हम "शुद्ध" ओओपी मानसिकता से बाध्य नहीं हैं। –

+0

http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class/16547184#16547184 –

उत्तर

64

निजी कन्स्ट्रक्टर का अर्थ है कि कोई उपयोगकर्ता सीधे कक्षा को तुरंत चालू नहीं कर सकता है। इसके बजाय, आप Named Constructor Idiom जैसे कुछ का उपयोग करके ऑब्जेक्ट्स बना सकते हैं, जहां आपके पास static क्लास फ़ंक्शंस हैं जो कक्षा के उदाहरण बना और वापस कर सकते हैं।

नामित कन्स्ट्रक्टर इडियोम एक वर्ग के अधिक सहज उपयोग के लिए है। सी ++ एफएक्यू में प्रदान किया गया उदाहरण एक वर्ग के लिए है जिसका उपयोग कई समन्वय प्रणालियों का प्रतिनिधित्व करने के लिए किया जा सकता है।

यह सीधे लिंक से खींचा जाता है। यह विभिन्न समन्वय प्रणालियों में बिंदुओं का प्रतिनिधित्व करने वाला एक वर्ग है, लेकिन यह आयताकार और ध्रुवीय समन्वय बिंदु दोनों का प्रतिनिधित्व करने के लिए उपयोग किया जा सकता है, ताकि उपयोगकर्ता के लिए इसे अधिक सहज बना दिया जा सके, विभिन्न कार्यों का उपयोग यह दर्शाता है कि Point लौटाई गई समन्वय प्रणाली का प्रतिनिधित्व करने के लिए विभिन्न कार्यों का उपयोग किया जाता है।

#include <cmath>    // To get std::sin() and std::cos() 

class Point { 
public: 
    static Point rectangular(float x, float y);  // Rectangular coord's 
    static Point polar(float radius, float angle); // Polar coordinates 
    // These static methods are the so-called "named constructors" 
    ... 
private: 
    Point(float x, float y);  // Rectangular coordinates 
    float x_, y_; 
}; 

inline Point::Point(float x, float y) 
    : x_(x), y_(y) { } 

inline Point Point::rectangular(float x, float y) 
{ return Point(x, y); } 

inline Point Point::polar(float radius, float angle) 
{ return Point(radius*std::cos(angle), radius*std::sin(angle)); } 

वहाँ अन्य जवाब है कि यह भी कारण है कि निजी कंस्ट्रक्टर्स कभी सी ++ (उन के बीच में सिंगलटन पैटर्न) में किया जाता है की भावना फिट का एक बहुत किया गया है।

एक और चीज जो आप इसके साथ कर सकते हैं prevent inheritance of your class है, क्योंकि व्युत्पन्न कक्षाएं आपके वर्ग के निर्माता तक पहुंच नहीं पाएंगी। बेशक, इस स्थिति में, आपको अभी भी एक ऐसे फ़ंक्शन की आवश्यकता है जो कक्षा के उदाहरण बनाता है।

+1

यकीन नहीं है, लेकिन कॉपी ctor होना अच्छा होगा। आरवीओ की वजह से इसके बारे में निश्चित नहीं है। –

+3

@ पावेल - सी ++ एफएक्यू उदाहरण 'प्वाइंट' के लिए कॉपी कन्स्ट्रक्टर को परिभाषित नहीं करता है क्योंकि कक्षा में केवल आदिम सदस्य (दो' फ्लोट') हैं, इसलिए कंपाइलर की डिफ़ॉल्ट प्रति कन्स्ट्रक्टर (जो उथले प्रतियां करता है) उदाहरण के लिए पर्याप्त है। – birryree

+1

+1 अंत में, एक उदाहरण जो सिंगलटन या फैक्ट्री नहीं है। नामित रचनाकार अधिक उपयोगी लगते हैं। – chrisaycock

29

एक आम उपयोग सिंगलटन पैटर्न में है जहां आप कक्षा के केवल एक उदाहरण मौजूद हैं। उस स्थिति में, आप static विधि प्रदान कर सकते हैं जो ऑब्जेक्ट का त्वरण करता है। इस तरह किसी विशेष वर्ग के तत्काल वस्तुओं की संख्या नियंत्रित की जा सकती है।

+17

+1। जब मैं एक विशेष मुहावरे के लिए केस-उपयोग के रूप में एक सिंगलटन का उल्लेख करता हूं तो मैं हमेशा नीचे आ जाता हूं। नहीं चाहते कि यह आपके साथ हो! :) –

2

जब आप सिंगलटन को कार्यान्वित करना चाहते हैं तो यह आम बात है। कक्षा में एक स्थिर "फैक्ट्री विधि" हो सकती है जो जांचती है कि कक्षा पहले से ही तत्काल हो चुकी है या नहीं, और अगर निर्माता नहीं है तो उसे कॉल करें।

5

अगर अन्य विधियां हैं जो उदाहरण उत्पन्न कर सकती हैं तो कन्स्ट्रक्टर को निजी बनाना उचित है। स्पष्ट उदाहरण पैटर्न सिंगलटन (प्रत्येक कॉल एक ही उदाहरण लौटाते हैं) और फैक्ट्री (प्रत्येक कॉल आमतौर पर नया उदाहरण बनाते हैं)।

1

उदाहरण के लिए, आप किसी मित्र वर्ग या मित्र फ़ंक्शन के अंदर एक निजी निर्माता का आह्वान कर सकते हैं।

Singleton pattern आम तौर पर यह सुनिश्चित करने के लिए इसका उपयोग करता है कि कोई भी इच्छित प्रकार के अधिक उदाहरण नहीं बनाता है।

6

निजी कन्स्ट्रक्टर उपयोगी होते हैं जब आप नहीं चाहते कि आपकी कक्षा उपयोगकर्ता द्वारा तत्काल हो। इस तरह के वर्गों को तुरंत चालू करने के लिए, आपको एक स्थिर विधि घोषित करने की आवश्यकता है, जो 'नया' करता है और पॉइंटर देता है।

निजी सीटर्स के साथ एक वर्ग एसटीएल कंटेनर में नहीं रखा जा सकता है, क्योंकि उन्हें एक प्रतिलिपि ctor की आवश्यकता होती है।

1

एक सामान्य उपयोग निम्नलिखित की तरह टेम्पलेट typedef वैकल्पिक हल कक्षाओं के लिए है:

template <class TObj> 
class MyLibrariesSmartPointer 
{ 
    MyLibrariesSmartPointer(); 
    public: 
    typedef smart_ptr<TObj> type; 
}; 

जाहिर है एक सार्वजनिक गैर कार्यान्वित निर्माता के रूप में अच्छी काम करेगा, लेकिन एक निजी कंसट्रक्टर एक लिंक टाइम त्रुटि के बजाय एक संकलन समय त्रुटि को जन्म देती है , अगर कोई MyLibrariesSmartPointer<SomeType>::type के बजाय MyLibrariesSmartPointer<SomeType> को स्थापित करने का प्रयास करता है, जो वांछनीय है।

संबंधित मुद्दे