सवाल हेडर क्या है?


क्या है <iosfwd> हेडर का उपयोग किया गया (में उल्लिखित यह फ़ाइल)?

यह जरूरी क्यों है?

कोई उदाहरण?


48
2017-11-29 03:47


मूल




जवाब:


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

यहां एक साधारण उदाहरण दिया गया है:

// foo.h
#include <iosfwd>

void sucker(std::iostream& is);

// foo.cc
#include <iostream>

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

47
2017-11-29 03:54



क्या आप विस्तार से समझा सकते हैं कि यह आगे के संदर्भ कैसे है? - wp2
@ wp2: यह सिर्फ उन्हें परिभाषित किए बिना प्रकार घोषित करता है। अपने अंदर एक झांक क्यों नहीं है? यह काफी छोटा है। - Marcelo Cantos
@ wp2: उत्तर पढ़ें, यह केवल एक वाक्य है। - MSalters
लेकिन आपको <iostream> अंत में वैसे भी शामिल करना होगा, है ना? - wp2
@ wp2: हां, लेकिन केवल .cpp फ़ाइल में, जिसमें foo.h का उपयोग करने वाली प्रत्येक एकल .cpp फ़ाइल की बजाय घोषणा की आवश्यकता होती है। - 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>, कंपाइलर को विभिन्न शीर्षलेख फ़ाइलों से कोड की 25 9 8 लाइनों को संसाधित करना होता है, जबकि एक फ़ाइल जिसमें शामिल है <iostream> कोड की एक बड़ी 25631 लाइनों को संसाधित करना है। यह उस वास्तविक कोड को संकलित करने से पहले है जिसे आप अपनी स्रोत फ़ाइल में रखते हैं!


27
2017-11-29 04:12



निम्न आदेश कैसे काम करता है, $ echo '# शामिल <iosfwd>' | जी ++ -E -xc ++ - | wc मैंने निम्न आदेश चलाने की कोशिश की लेकिन यह कुछ त्रुटि $ echo '# शामिल <QtGlobal>' | जी ++ -E -xc ++ - | डब्ल्यूसी मैं कहाँ गलत था? - beparas


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

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

मैंने यह लिंक कण उपयोगी पाया: http://www.gotw.ca/gotw/007.htm


8
2017-07-17 08:33



पहले से मौजूद और 2 साल से अधिक पुराने उत्तरों की तुलना में यह और अधिक अंतर्दृष्टिपूर्ण है। - Christian Rau
मैं इस धारणा के तहत था कि यह एक निर्माण अनुकूलन का अधिक है: संकलन करने में बहुत कम समय लगता है <iosfwd> से <iostream>। या क्या वह एप्लिकेशन आप जो कह रहे थे उसका मुख्य जोर है? - Hurkyl