फ़ाइलों को किस क्रम में निर्दिष्ट किया जाना चाहिए, यानी एक से पहले एक हेडर सहित क्या कारण हैं?
उदाहरण के लिए, क्या सिस्टम फ़ाइलें, एसटीएल और बूस्ट स्थानीय शामिल होने से पहले या बाद में फ़ाइलें शामिल हैं?
फ़ाइलों को किस क्रम में निर्दिष्ट किया जाना चाहिए, यानी एक से पहले एक हेडर सहित क्या कारण हैं?
उदाहरण के लिए, क्या सिस्टम फ़ाइलें, एसटीएल और बूस्ट स्थानीय शामिल होने से पहले या बाद में फ़ाइलें शामिल हैं?
जवाबों:
मुझे नहीं लगता कि जब तक यह संकलित है, तब तक एक अनुशंसित आदेश नहीं है! क्या कष्टप्रद है जब कुछ हेडर को पहले शामिल करने के लिए अन्य हेडर की आवश्यकता होती है ... यह हेडर के साथ एक समस्या है, जिसमें शामिल के क्रम के साथ नहीं है।
मेरी व्यक्तिगत प्राथमिकता स्थानीय से वैश्विक स्तर तक जाने की है, प्रत्येक वर्णमाला के क्रम में है, अर्थात:
1 के लिए मेरा तर्क यह है कि यह साबित होना चाहिए कि प्रत्येक हेडर (जिसके लिए एक सीपीपी है) को #include
किसी और चीज के बिना डी किया जा सकता है (टर्मिनस टेक्निकस: हेडर "स्व-निहित" है)। और बाकी सिर्फ तार्किक रूप से वहाँ से प्रवाह करने लगता है।
ध्यान रखने वाली बड़ी बात यह है कि आपके हेडर को पहले शामिल किए जा रहे अन्य हेडर पर निर्भर नहीं होना चाहिए। इसका बीमा करने का एक तरीका यह है कि आप अपने हेडर को किसी अन्य हेडर से पहले शामिल करें।
"सी ++ में सोच" विशेष रूप से इसका उल्लेख करते हैं, लैकोस का "बड़े पैमाने पर सी ++ सॉफ्टवेयर डिज़ाइन" का संदर्भ देते हुए:
अव्यक्त उपयोग त्रुटियों को सुनिश्चित करने से बचा जा सकता है। घटक फ़ाइल के .h फ़ाइल को अपने आप से - बिना किसी बाहरी घोषणा या परिभाषा के ... .h फ़ाइल को .c फ़ाइल की पहली पंक्ति के रूप में शामिल करना सुनिश्चित करता है कि कोई महत्वपूर्ण अंश नहीं है। घटक के भौतिक इंटरफ़ेस के लिए आंतरिक जानकारी की जानकारी .h फ़ाइल से गायब है (या, यदि वहाँ है, कि जैसे ही आप .c फ़ाइल को संकलित करने का प्रयास करेंगे) आपको इसके बारे में पता चल जाएगा।
यह कहना है, निम्नलिखित क्रम में शामिल करें:
यदि किसी भी हेडर में इस क्रम में शामिल होने के साथ कोई समस्या है, तो उन्हें (यदि आपका) ठीक करें या उनका उपयोग न करें। बहिष्कार पुस्तकालयों कि स्वच्छ हेडर नहीं लिखते हैं।
Google का C ++ स्टाइल गाइड लगभग उल्टा तर्क देता है , जिसमें वास्तव में कोई औचित्य नहीं है; मैं व्यक्तिगत रूप से लैकोस दृष्टिकोण का पक्ष लेता हूं।
मैं दो सरल नियमों का पालन करता हूं जो अधिकांश समस्याओं से बचते हैं:
मैं निम्नलिखित दिशानिर्देशों का भी पालन करता हूं:
दूसरे शब्दों में:
#include <stdio.h>
#include <string.h>
#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"
हालांकि, दिशानिर्देश होने के नाते, यह एक व्यक्तिपरक बात है। दूसरी ओर, मैं सख्ती से लागू करता हूं, यहां तक कि गार्ड और समूहीकृत के साथ 'रैपर' हेडर फ़ाइलों को प्रदान करने के बिंदु तक भी शामिल है अगर कुछ अप्रिय तीसरे पक्ष के डेवलपर मेरी दृष्टि की सदस्यता नहीं लेते हैं :-)
दीवार में अपनी ईंट जोड़ने के लिए।
इसलिए मैं आमतौर पर इस तरह से जाता हूं:
// myproject/src/example.cpp
#include "myproject/example.h"
#include <algorithm>
#include <set>
#include <vector>
#include <3rdparty/foo.h>
#include <3rdparty/bar.h>
#include "myproject/another.h"
#include "myproject/specific/bla.h"
#include "detail/impl.h"
प्रत्येक समूह अगले एक से एक रिक्त रेखा द्वारा अलग हो गया:
यह भी ध्यान दें कि, सिस्टम हेडर के अलावा, प्रत्येक फ़ाइल अपने नेमस्पेस के नाम के साथ एक फ़ोल्डर में है, सिर्फ इसलिए कि उन्हें इस तरह से ट्रैक करना आसान है।
#define
जो अन्य कोड को गड़बड़ करते हैं) और अंतर्निहित निर्भरता को रोकने के लिए खराब हैं । उदाहरण के लिए, यदि हमारी कोड बेस हेडर फाइल foo.h
वास्तव में निर्भर करती है, <map>
लेकिन हर जगह इसका इस्तेमाल .cc
फाइलों में <map>
होता है, तो पहले से ही शामिल होने के लिए हुआ, हम शायद नोटिस नहीं करेंगे। जब तक किसी foo.h
को पहले शामिल किए बिना शामिल करने की कोशिश की <map>
। और फिर वे नाराज हो जाते।
.h
में कम से कम एक है .cpp
जो इसे पहले शामिल करता है (वास्तव में, मेरे व्यक्तिगत कोड में यूनिट परीक्षण में पहले इसे शामिल किया गया है, और स्रोत कोड ने इसे अपने सही समूह में शामिल किया है )। प्रभावित न होने के संबंध में, यदि किसी भी हेडर में शामिल है, <map>
तो बाद में शामिल सभी हेडर वैसे भी प्रभावित होते हैं, इसलिए यह मेरे लिए एक हारी हुई लड़ाई लगती है।
Header corresponding to this cpp file first (sanity check)
। क्या कुछ विशेष है अगर #include "myproject/example.h"
सभी को शामिल किया गया है?
मेरा सुझाव है:
और निश्चित रूप से, जहां संभव हो, प्रत्येक अनुभाग के भीतर वर्णमाला क्रम।
#include
अपनी हेडर फ़ाइलों में अनावश्यक एस से बचने के लिए हमेशा आगे की घोषणाओं का उपयोग करें।
मुझे पूरा यकीन है कि यह समझदार दुनिया में कहीं भी एक अनुशंसित अभ्यास नहीं है, लेकिन मुझे लाइन सिस्टम पसंद है जिसमें फ़ाइल नाम लंबाई, समान रूप से एक ही लंबाई के भीतर क्रमबद्ध शामिल है। इस तरह:
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
मुझे लगता है कि अन्य लोगों से पहले अपने स्वयं के हेडर को शामिल करना एक अच्छा विचार है, शामिल-ऑर्डर निर्भरता की शर्म से बचने के लिए।
windows.h
।
यह व्यक्तिपरक नहीं है। सुनिश्चित करें कि आपके हेडर #include
विशिष्ट क्रम में d होने पर निर्भर नहीं हैं । आप सुनिश्चित कर सकते हैं कि इससे कोई फर्क नहीं पड़ता कि आप एसटीएल या बूस्टर हेडर को किस क्रम में शामिल करते हैं।
पहले शीर्ष लेख को .cpp के अलावा शामिल करें ... दूसरे शब्दों में, कुछ भी source1.cpp
शामिल करने source1.h
से पहले शामिल करना चाहिए । एकमात्र अपवाद जो मैं सोच सकता हूं, जब पूर्व-संकलित हेडर के साथ MSVC का उपयोग कर रहे हैं, तो आप stdafx.h
किसी भी अन्य चीज से पहले शामिल होने के लिए मजबूर हैं ।
रीज़निंग:source1.h
किसी भी अन्य फ़ाइलों को शामिल करने से पहले यह सुनिश्चित करता है कि यह निर्भरता के बिना अकेले खड़ी हो सकती है। यदि source1.h
बाद की तारीख पर निर्भरता लेता है, तो संकलक आपको तुरंत आवश्यक घोषणाओं को जोड़ने के लिए सचेत करेगाsource1.h
। यह बदले में यह सुनिश्चित करता है कि हेडर को उनके आश्रितों द्वारा किसी भी क्रम में शामिल किया जा सकता है।
उदाहरण:
source1.h
class Class1 {
Class2 c2; // a dependency which has not been forward declared
};
source1.cpp
#include "source1.h" // now compiler will alert you saying that Class2 is undefined
// so you can forward declare Class2 within source1.h
...
MSVC उपयोगकर्ता: मैं पूर्व संकलित हेडर का उपयोग करने की दृढ़ता से सलाह देता हूं। इसलिए, #include
मानक हेडर (और अन्य हेडर जो कभी बदलने नहीं जा रहे हैं) के लिए सभी निर्देशों को स्थानांतरित करें stdafx.h
।
सबसे विशिष्ट से कम से कम विशिष्ट को शामिल करें, .cpp के लिए इसी .hpp से शुरू करें, अगर ऐसा मौजूद है। इस तरह, हेडर फ़ाइलों में छिपी निर्भरताएं जो आत्मनिर्भर नहीं हैं, वे प्रकट हो जाएंगी।
यह पूर्व संकलित हेडर के उपयोग से जटिल है। इसके आसपास एक तरीका यह है कि आपकी परियोजना को संकलित किए बिना, एक प्रोजेक्ट हेडर का उपयोग करना है क्योंकि पहले से तैयार हेडर में फ़ाइल शामिल है।
यह मानक से परे कई तत्वों के साथ, सी / सी ++ दुनिया में एक कठिन सवाल है।
मुझे लगता है कि जब तक यह संकलित नहीं होता है, हेडर फ़ाइल ऑर्डर एक गंभीर समस्या नहीं है।
मेरा विचार है: यदि उन सभी शीर्ष लेखों में प्रतीकों का कोई विरोध नहीं है, तो कोई भी आदेश ठीक है, और शीर्ष लेख पर निर्भरता समस्या बाद में #include पंक्तियों को त्रुटिपूर्ण .h में जोड़कर तय की जा सकती है।
असली परेशानी तब होती है जब कुछ हेडर ऊपर की चीज़ों के अनुसार अपनी कार्रवाई (# एफ़आई शर्तों की जाँच करके) बदल देते हैं।
उदाहरण के लिए, VS2005 में stddef.h में है:
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
अब समस्या: यदि मेरे पास एक कस्टम हेडर ("custom.h") है, जिसे कई कंपाइलरों के साथ उपयोग करने की आवश्यकता है, जिसमें कुछ पुराने भी शामिल हैं जो offsetof
उनके सिस्टम हेडर में प्रदान नहीं करते हैं, मुझे अपने हेडर में लिखना चाहिए:
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
और सभी सिस्टम हेडर के #include "custom.h"
बाद उपयोगकर्ता को बताना सुनिश्चित करें , अन्यथा, offsetof
stddef.h की लाइन मैक्रो रिडिफाइनमेंट त्रुटि को मुखर करेगी।
हम अपने करियर में इस तरह के किसी भी मामले को पूरा नहीं करने की प्रार्थना करते हैं।