2009-01-04 9 views
20

मेरे पास हेडर फ़ाइलों के उपयोग पर निम्नलिखित संदेह हैं।सी ++ हेडर फाइलों के उपयोग के लिए सर्वोत्तम अभ्यास

1 - टिप्पणी के बाद रखने गार्ड शामिल करें

/* Copyright Note and licence information (multiple lines) */ 
#ifndef FOO_H 
#define FOO_H 
// Header file contents 
#endif 

हर्ब Sutter अपने में कहते हैं, "सी ++ कोडिंग मानकों" बुक ऊपर की तरह है कि कोड समस्याग्रस्त है। वह कह रहा है कि "#ifndef" कथन हेडर फ़ाइल की पहली पंक्ति में दिखाई देना चाहिए। मुझे यह विश्वास के रूप में महसूस नहीं हुआ है। क्या यह आपके द्वारा हेडर फ़ाइलों में लोगों/gals के बाद है?

2 - हेडर फाइल

#ifndef FOO_H 
#define FOO_H 
namespace FooNameSpace{ 
    // Header file contents 
} 
#endif 

में नामस्थान का उपयोग करते हुए उपरोक्त कोड सही व्यवहार का उपयोग कर है? मेरा मतलब है, क्या आप हेडर फाइलों में नेमस्पेस का उपयोग करते हैं? मुझे पता है कि हेडर फ़ाइल में नेमस्पेस आयात करना व्यर्थ है लेकिन ऊपर की तरह एक घोषणा के बारे में क्या है?

यदि उपरोक्त एक सही तरीका है, तो आप किसी अन्य नामस्थान में एक वर्ग के "आगे की घोषणा" कैसे करते हैं? ऐसा लगता है जैसे

#ifndef FOO_H 
#define FOO_H 
namespace AnotherNameSpace{ 
    class AnotherFoo; // forward declaration 
} 

namespace FooNameSpace{ 
    // Use AnotherFoo here 
} 
#endif 

"आगे घोषणा" है केवल विधि "चक्रीय निर्भरता" से बचने के लिए, सही है?

उत्तर

19
  1. शामिल गार्ड और टिप्पणियों का क्रम पूरी तरह स्टाइल का मामला है - इसका संकलन की गति पर कोई मापनीय प्रभाव नहीं होगा।

  2. नेमस्पेस बिल्कुल काम करता है, कक्षाएं, वैश्विक, आदि घोषित करने के लिए शीर्षक फ़ाइलें में इस्तेमाल किया जाना चाहिए क्या आपको चाहिए नहीं कर हेडर फाइल में using बयानों का उपयोग है - यह एक स्रोत फ़ाइल है जिसमें शामिल हैं में कुछ unuse करना असंभव है यह, और आपको वैश्विक दायरे में अतिरिक्त सामान जोड़ने के लिए शामिलकर्ताओं को मजबूर नहीं करना चाहिए। यदि आपको अपने शीर्षकों में अन्य नामस्थानों से चीजों का उपयोग करने की आवश्यकता है, तो प्रत्येक नाम को पूरी तरह अर्हता प्राप्त करें। यह कभी-कभी दर्द हो सकता है, लेकिन यह वास्तव में करना सही है।

उदाहरण:

// WRONG! 
using namespace std; 
class MyClass 
{ 
    string stringVar; 
}; 

// RIGHT 
class MyClass 
{ 
    std::string stringVar; 
}; 

अन्य नामस्थान में वर्गों के आगे घोषणाओं का सवाल है, तो आप इसे बिल्कुल सही मिल गया है। जब आप इसे अपने हेडर के अंदर संदर्भित करते हैं तो AnotherFooAnotherNameSpace::AnotherFoo के रूप में हमेशा योग्यता प्राप्त करना याद रखें। वास्तव में, आगे की घोषणा चक्रवात निर्भरताओं को तोड़ने का एकमात्र तरीका है।

3

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

2

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

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

7
  1. मैंने सुना है कि टिप्पणियों होने से पहले गार्ड शामिल कुछ compilers एक अनुकूलन याद आती है हो सकता है। यदि गार्ड बहुत पहली बात है, तो संकलक मुहावरे को पहचान सकता है और के लिए शीर्षलेख खोलने की परेशानी भी शामिल नहीं है। अपने कोड में, आमतौर पर से पहले गार्ड शामिल हैं। मैंने कभी को यह देखने के लिए परेशान परीक्षण नहीं किया है कि इसमें कोई प्रभाव है या नहीं। और शायद मैं कभी नहीं करूंगा (लेकिन अगर कोई और करता है, तो मुझे परिणामों में दिलचस्पी होगी)।

  2. पाठ्यक्रम हेडर की

    नामस्थान शामिल करना चाहिए - अन्यथा कुछ भी नहीं उपयोगी कभी एक नाम स्थान के अंदर हो सकता है। हालांकि, जैसा कि आप का उल्लेख करते हैं, शीर्षलेख 'आयात' (बेहतर शब्द की इच्छा के लिए) नामांकन को संकलन इकाई में 'using' निर्देश के साथ नहीं होना चाहिए।

2
  1. मैं टिप्पणियां जोड़ने नहीं लगता कि किसी भी प्रदर्शन प्रभाव के रूप में इस पोस्ट के लिए एडम जवाब से इशारा किया है।

  2. मैंने हेडर फ़ाइलों में नामस्थानों का उपयोग किया है, यदि आप स्ट्रिंग क्लास के स्वामी को परिभाषित करते हैं, तो यह std नेमस्पेस स्ट्रिंग क्लास के साथ संघर्ष करेगा।

का उपयोग करना "का उपयोग करके" कीवर्ड से सटीक गलत नहीं है

+5

एक स्रोत फ़ाइल में (क्योंकि यह आप सुविधा का एक बहुत और बहुत कम अपने सभी चर से पहले टाइप करने के लिए देता है), का उपयोग करते हुए "का उपयोग" नहीं है बिल्कुल गलत, लेकिन एक हेडर फ़ाइल में, यह बहुत गलत है। –

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