2011-04-14 20 views
22

(सी ++ में) मेरे पास एक वर्ग है जिसका संरचना हेडर फ़ाइल में घोषित की गई है। उस शीर्षलेख फ़ाइल को कई स्रोत फ़ाइलों में शामिल किया गया है, जैसे कि जब मैं इसे संपादित करता हूं तो मुझे बहुत सारी फ़ाइलों को पुन: संकलित करने की आवश्यकता होती है।कक्षा शीर्षलेख फ़ाइलों (सी ++) में निजी कार्यों की घोषणा करने से बचें

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

मैं इसे कैसे प्राप्त कर सकता हूं?

+0

ऐसे दृष्टिकोण हैं जो अच्छी तरह से काम करते हैं यदि मैं कक्षा को स्क्रैच से लिख रहा था। हालांकि, मैं खरोंच से शुरू नहीं कर रहा हूँ; यह कक्षा पहले से ही लिखी गई है। – user664303

उत्तर

4

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

header.h:

class FooImpl; 

class Foo { 
public: 
    int bar(); 
    friend class FooImpl; 
private: 
    int var; 
} 

impl.cpp:

#include "header.h" 

class FooImpl { 
public: 
    int bar(Foo &); 
} 

int FooImpl::bar(Foo &foo) { 
return foo.var; 
} 

int Foo::bar() { 
return FooImpl::bar(*this); 
} 
+0

यह मेरी समझ अब तक है, लेकिन मैं 100% निश्चित नहीं हूं। टिप्पणियां कृतज्ञता से प्राप्त हुईं। – user664303

+0

आपके पास अभी भी 'कक्षा फू' में 'int var' है। सवाल का पूरा बिंदु यह नहीं है कि इसे 'कक्षा FooImpl' पर ले जाएं? – balki

+1

@balki: नहीं, इस प्रश्न का पूरा बिंदु हेडर को बदलने के बिना, कक्षा में निजी _functions_ को जोड़ने या संपादित करने का तरीका था। यदि मैं निजी चर को FooImpl में ले जाता हूं तो मुझे उस मौजूदा वर्ग के सभी मौजूदा कार्यों को भी आगे बढ़ाना होगा। इसके बारे में एरिक के जवाब पर मेरी पहली टिप्पणी देखें। – user664303

14

pImpl idiom का उपयोग करें - आपकी दृश्यमान कक्षा वास्तविक कक्षा में पॉइंटर रखती है और आगे सार्वजनिक सदस्य कार्यों को कॉल करती है।

संपादित करें: टिप्पणियाँ

// Foo.h: 

class FooImpl; // Do *not* include FooImpl.h 
class Foo { 
public: 
    Foo(); 
    ~Foo(); 
    //.. also need copy ctor and op= 
    int bar(); 
private: 
    FooImpl * Impl; 
}; 

// FooImpl.h: 

class FooImpl { 
public: 
    int bar() { return Bar; } 
private: 
    int Bar; 
}; 

// Foo.cpp: 

#include "FooImpl.h" 

Foo::Foo() { Impl = new FooImpl(); } 
Foo::~Foo() { delete Impl; } 
int Foo::bar() { return Impl->bar(); } 

FooImpl में अपने वर्ग के वास्तविक क्रियान्वयन रखें के जवाब में - FooFooImpl की सार्वजनिक सदस्यों की प्रतियां होना चाहिए और केवल आगे इन करने के लिए कहता है। सभी उपयोगकर्ताओं में केवल "Foo.h" शामिल होगा - आप FooImpl के सभी निजी विवरण Foo के उपयोगकर्ताओं के बिना किसी भी परिवर्तन को देख सकते हैं।

+0

धन्यवाद। यह सामान्य रूप से एक अच्छा विचार है। हालांकि, इस मामले में मैंने इस ढांचे का उपयोग शुरू नहीं किया, इसलिए इसके लिए आगे बढ़ने के लिए मेरे वर्ग के व्यापक पुनर्लेख की आवश्यकता होगी, जिसमें सभी सार्वजनिक कार्यों के लिए लेखन रैपर भी शामिल हैं। मैं बिना किसी परेशानी के, हेडर से बाहर निजी कार्यों का एक सबसेट भेजना चाहता हूं। – user664303

+0

@ user664303: विरासत * एक समाधान हो सकता है - यह विशेष समस्या सी ++ आईएमओ की परेशानियों में से एक है। – Erik

+0

क्या मैं सोच रहा हूं कि इसे क्लास इंस्टेंस पॉइंटर की एक कलाकार की आवश्यकता होगी, उदाहरण: ((priv_class *) यह) -> priv_func(); या इससे बचने का कोई तरीका है? – user664303

1

एक सार आधार वर्ग है जो केवल सार्वजनिक कार्यों और अपने हेडर में संदर्भ यह होता है बनाएँ। कहीं और एक कार्यान्वयन के रूप में अपनी असली कक्षा बनाएँ। केवल स्रोत फ़ाइलों को जो आपकी कक्षा बनाने की आवश्यकता है कार्यान्वयन वर्ग शीर्षलेख देखने की आवश्यकता है।