2010-11-29 7 views

उत्तर

43

ऐसा इसलिए है कि आप अपने स्वयं के शीर्षकों में घोषित कर सकते हैं, जो iostream प्रकारों की घोषणाओं पर भरोसा करते हैं, जो #include iostream हेडर स्वयं के बिना हैं, जो बड़े, जटिल और संकलित करने में धीमे होते हैं।

// foo.h 
#include <iosfwd> 

void sucker(std::iostream& is); 

 

// foo.cc 
#include <iostream> 

void sucker(std::iostream& is) { 
    is >> somevar; 
} 
+0

आप यह कैसे संदर्भ अग्रेषित करता विस्तार से व्याख्या कर सकते हैं? – wp2

+0

@ wp2: यह सिर्फ उन्हें परिभाषित किए बिना प्रकार घोषित करता है। अपने अंदर एक झांक क्यों नहीं है? यह काफी छोटा है। –

+0

foo.cc में सीधे इसे करने के बजाय foo.cc में '#' शामिल करने का लाभ क्या है? – wp2

27

@Marcelo Cantos उल्लेख किया है, यह तो आप पूर्ण परिभाषाओं को शामिल किए बिना iostream वर्गों और कार्यों की घोषणा में शामिल कर सकते हैं:

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

अक्सर आप केवल का उपयोग-में एक समारोह के मामले के लिए कुछ की घोषणा की जरूरत है, आप डॉन ':

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

परिभाषाओं के बजाय घोषणाओं को शामिल करके, संकलक को संसाधित करने वाले कोड की कुल मात्रा बहुत कम है, और इसलिए संकलन अधिक तेज़ी से आगे बढ़ेगा।

आप कितना कोड संसाधित किया जा रहा है की एक विचार देने के लिए, यहाँ कितना कोड अपने स्थानीय कार्यान्वयन में निहित है है:

# The following commands create a source file that includes a single header 
# file (on stdout), preprocess it with g++ -E, and then count how many lines 
# are in the resulting preprocessed output 
$ echo '#include <iosfwd>' | g++ -E -xc++ - | wc 
    2598 6534 57875 
$ echo '#include <iostream>' | g++ -E -xc++ - | wc 
    25631 59613 631998 

एक फ़ाइल है कि <iosfwd> भी शामिल है, संकलक कोड की 2598 लाइनों पर कार्रवाई करने के है विभिन्न शीर्षलेख फ़ाइलों से, जबकि एक फ़ाइल जिसमें <iostream> शामिल है, को कोड की एक बड़ी 25631 लाइनों को संसाधित करना है। यह उस वास्तविक कोड को संकलित करने से पहले है जिसे आप अपनी स्रोत फ़ाइल में रखते हैं!

+0

निम्न आदेश कैसे काम करता है, $ echo '# शामिल करें ' | जी ++ -E -xC++ - | wc मैंने निम्न आदेश चलाने की कोशिश की लेकिन यह कुछ त्रुटि $ echo '# शामिल करें ' | जी ++ -E -xC++ - | wc जहां मैं गलत था? – beparas

8

मूल रूप से जब आप <iosfwd> का उपयोग करते हैं तो आप संकलन-समय निर्भरता को खत्म करना चाहते हैं।

पारंपरिक स्ट्रीम हेडर (<iostream> और दोस्तों) के बजाय आप <iosfwd> का उपयोग करते हैं ताकि आप संपूर्ण स्ट्रीमिंग सामग्री की परिभाषा को टालने से बच सकें। <iosfwd> के साथ आप केवल सभी स्ट्रीमिंग सामग्री की अग्रेषित घोषणा कर रहे हैं।

मैं इस लिंक खासकर उपयोगी पाया: http://www.gotw.ca/gotw/007.htm

+2

किस तरह से पहले से मौजूद और 2 साल से अधिक पुराने उत्तरों की तुलना में यह अधिक अंतर्दृष्टिपूर्ण है। –

+0

मैं इस धारणा के तहत था कि यह एक बिल्ड ऑप्टिमाइज़ेशन का अधिक है: '' से ' 'संकलित करने में बहुत कम समय लगता है। या क्या वह एप्लिकेशन आप जो कह रहे थे उसका मुख्य जोर है? – Hurkyl

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