2014-10-19 6 views
6

कई मामलों में मुझे अपने वर्गों को अपनी कार्यक्षमता को तोड़ने और कोड का पुन: उपयोग करने के लिए निजी कार्यों की आवश्यकता होती है। ठेठ कार्यान्वयन होगा:क्या केवल .cpp में स्थिर विधि घोषित/परिभाषित करना ठीक है?

MyClass.h

#include "AnotherClass.h" 

class MyClass { 
public: 
    float foo() const; 
private: 
    float fooPrivate(const AnotherClass& ac) const; 
} 

MyClass.cpp

#include "MyClass.h" 

float MyClass::foo() const { 
    return fooPrivate(AnotherClass()); 
} 
float MyClass::fooPrivate(const AnotherClass& ac) const { 
    return ac.foo(); 
} 

यह ठीक है, लेकिन हेडर फाइल में fooPrivate() की घोषणा निम्नलिखित मामलों में समस्या हो सकती है :

  • हम हेडर फ़ाइल में अन्य क्लास को शामिल नहीं करना चाहते हैं अगर यह केवल आंतरिक उपयोग के लिए और MyClass के बाहर की आवश्यकता नहीं है।

  • यदि कई निजी कार्यों की आवश्यकता है तो हम हेडर फ़ाइल को अनावश्यक निजी कार्यों के साथ प्रदूषित करने का जोखिम उठाते हैं जो कोड को कम स्पष्ट करते हैं, संकलन समय बढ़ाते हैं और बनाए रखना अधिक कठिन होता है।

मैं Pimpl मुहावरा है कि इन सभी समस्याओं को हल करती है के बारे में पता कर रहा हूँ, लेकिन मेरे सवाल यह है कि अगर हम Pimpl उपयोग करने के लिए कुछ कार्यों के लिए इस तरह कुछ करने के लिए यह ठीक है नहीं करना चाहते?

MyClass.h

class MyClass { 
public: 
    float foo() const; 
} 

MyClass.cpp

#include "MyClass.h" 
#include "AnotherClass.h" 

static float fooPrivate(const AnotherClass& ac) { 
    return ac.foo(); 
} 
float MyClass::foo() const { 
    return fooPrivate(AnotherClass()); 
} 

इस मामले में यह MyClass.h और fooPrivate() में AnotherClass.h शामिल करने के लिए की जरूरत नहीं है किसी के द्वारा नहीं कहा जा सकता MyClass.cpp के अंदर और इसे घोषित करने के बाद छोड़कर। क्या मैं सही हू?

क्या इसका उपयोग कर कोई चेतावनी है या जब मैं अपना प्रोग्राम बड़ा हो जाता हूं तो क्या समस्याएं खत्म हो जाती हैं?

+0

ऐसा लगता है कि आपका निजी सदस्य कार्य 'fooPrivate' पहले स्थान पर स्थिर हो सकता था। अन्यथा, आपका दूसरा दृष्टिकोण इतना अच्छा काम नहीं करेगा। –

+0

आप जानते हैं, हेडर के लिए 'अन्य क्लास' के लिए एक अग्रेषित घोषणा पर्याप्त है। वह हल्का हल्का है। – Deduplicator

+0

मैं आपको समझता हूं। हालांकि बिंदु एक ही रहता है। यहां तक ​​कि अगर fooPrivate() MyClass के कुछ सदस्यों का उपयोग करता है (जो इसे गैर स्थैतिक बना देगा), ऐसे कई मामले हैं जहां कुछ सामग्री करने के लिए स्थिर फ़ंक्शन का उपयोग किया जा सकता है और फिर इस कॉल को संशोधित करने के लिए स्थिर कॉल के परिणाम का उपयोग किया जा सकता है । –

उत्तर

11

वास्तव में, न केवल यह ठीक है, मैं वास्तव में इसकी अनुशंसा करता हूं।

private कार्यों इस्तेमाल हो सकता है जा, और कभी कभी चाहिए (जब निजी तत्वों तक पहुँचने) लेकिन वहाँ उन लोगों के साथ एक मुद्दा है: भले ही वह केवल एक घोषणा है, वे वर्ग परिभाषा को अस्त-व्यस्त: एक उपयोगकर्ता की वर्ग को कक्षा के आंतरिक लोगों की देखभाल या संपर्क नहीं करना चाहिए।

दूसरी तरफ, static किसी स्रोत फ़ाइल में अज्ञात नेमस्पेस में घोषित फ़ंक्शंस या फ़ंक्शंस "मुफ़्त" हैं। कोई फर्क नहीं पड़ता उनमें से कितने आप:

  • वे Itanium ABI संकलक उपकरण-चेन पर हैडर
  • अव्यवस्थित नहीं करते (उदाहरण के लिए), वे, एक निर्यात प्रतीक की ओर नहीं ले लोड समय
  • को तेज

यदि कोई नकारात्मक पक्ष है, हालांकि, यह है कि उन इटेनियम से संबंधित टूल-चेन पर उनकी अनुपस्थिति नाम की अनुपस्थिति खराब बैकट्रैस के बिना होती है। हालांकि इसे मामूली असुविधा के रूप में देखा जा सकता है।

नोट: कक्षा के सदस्यों को सीधे private सदस्यों तक पहुंच नहीं है, शायद ही कभी कोई समस्या है क्योंकि कक्षा की विधि आसानी से उन सदस्यों के संदर्भ को पार कर सकती है। इसका मतलब यह है कि जब वे रचनाकार सार्वजनिक नहीं होते हैं तो वे कक्षा का एक उदाहरण नहीं बना सकते हैं।

+1

+1 के लिए –

+0

आप किस इटेनियम से संबंधित टूलचेन के बारे में बात कर रहे हैं? Itanium खुद ही आजकल पूरी तरह से अप्रासंगिक है, है ना? –

+1

@avl_sweden: मैं (भ्रमित) [इटेनियम एबीआई] (https://itanium-cxx-abi.github.io/cxx-abi/) के बारे में बात कर रहा हूं, जो क्लैंग, जीसीसी, आईसीसी द्वारा उपयोग की जाने वाली एबीआई है। .. –

6

मामूली असुविधा को छोड़कर, कोई चेतावनी नहीं है। आपका स्थैतिक कार्य स्पष्ट रूप से एक वर्ग विधि नहीं होने वाला है। इसके कारण, यह केवल सार्वजनिक वर्ग के सदस्यों और विधियों तक पहुंच सकता है।

3

चूंकि आपके सहायक कार्य केवल क्लास कार्यान्वयन-फ़ाइल में उपलब्ध स्थिर फ़ंक्शन का उपयोग करके कक्षा के सार्वजनिक इंटरफ़ेस का उपयोग करते हैं, ठीक है।

वैसे भी, अपने उदाहरण वास्तव में AnotherClass की परिभाषा की आवश्यकता नहीं थी, एक हल्के आगे की घोषणा ठीक हो गया होता:

class AnotherClass; 

इसके अलावा, मैं सामान्य सिद्धांतों पर दोनों ही मामलों में समारोह inline को चिह्नित करना होगा, iff इसका उपयोग केवल कार्यान्वयन द्वारा किया जाता है, और यह सब एक ही अनुवाद-इकाई में है:
बेहतर प्रदर्शन/छोटे कोड के बिना किसी भी डाउनसाइड्स के थोड़े मौके होंगे।

+1

+1! यह अब तक का सबसे स्पष्ट उत्तर है। आपके समय के लिए धन्यवाद। –

4

मैं कभी-कभी ऐसा करता हूं, "सहायक कार्यों" के लिए जो सचमुच कक्षा के सार्वजनिक इंटरफ़ेस में जो भी उपयोग नहीं करते हैं। मैं इस पैटर्न के उपयोग को कम करने की कोशिश करता हूं क्योंकि private चरों तक कोई पहुंच नहीं है। हालांकि, नि: शुल्क फ़ंक्शन अच्छा चीज़ और arguably भी increase encapsulation हैं।

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