2010-06-24 6 views
5

क्या वर्णन या इस का अर्थ है: उदाहरण के लिए:आगे की घोषणा का उद्देश्य क्या है?

class test; 

class test 
{ 
    ..... 
}; 
+2

अगली बार जब आप एक शीर्षक प्राप्त करना चाहते हैं जो वास्तव में ** ** शीर्षक है :) – ereOn

+4

एक सार्थक शीर्षक रखने के लिए अपने प्रश्न को संपादित करें। – Puppy

+0

यह http://stackoverflow.com/questions/2632601/why-are-forward-declarations-necessary का डुप्लिकेट जैसा लगता है, जो डुप्लिकेट होने के लिए बंद था। सर्कुलर संदर्भों पर चर्चा के लिए – Ferruccio

उत्तर

4

पहले, वर्ग घोषित है, तो यह परिभाषित है।

घोषणा: यह केवल कंपाइलर को बताता है: ठीक है, यहां कुछ (विधि, वर्ग, आदि) है, जिसका उपयोग दिए गए नाम से किया जा सकता है। यह सिर्फ बाइंड कुछ दिया गया नाम है।

परिभाषा: यह संकलक को बताता है: ठीक है, यहां क्या है (और कैसे) विधियां, कक्षाएं, वास्तव में उनकी सामग्री करते हैं। अगर कुछ परिभाषित किया गया है, तो संकलक वास्तव में स्थान आवंटित करने के कारण होता है।

आप here पर एक नज़र डाल सकते हैं।

0

एहम, सवाल बहुत स्पष्ट नहीं है। हालांकि, आपूर्ति की गई कोड एक कक्षा test घोषित करती है और वास्तविक सदस्यों को छोड़कर इसे नीचे परिभाषित करती है (...)।

1

पहली पंक्ति जिसे आगे की घोषणा कहा जाता है। यह कक्षा के नाम को वर्तमान नामस्थान में वास्तव में परिभाषित किए बिना लाता है।

0

सरल उत्तर यह है कि जब आप पहले फॉर्म का उपयोग करते हैं, तो आप पूर्ण कार्यान्वयन की आवश्यकता के बिना कक्षा में पॉइंटर्स या संदर्भ रख सकते हैं। यह बहुत उपयोगी हो सकता है जब दो वर्ग कसकर बातचीत करते हैं और उनके कार्यान्वयन या परिभाषाओं को अलग करना कठिन होता है।

21

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

class B; 

class A { 
    B* b; 
}; 

class B { 
    A* a; 
}; 

बी के लिए आगे संदर्भ के बिना, संकलक सफलतापूर्वक एक के लिए परिभाषा पार्स नहीं कर सके और आप ए

से पहले बी की परिभाषा डालने की तरह एक भाषा में यह समस्या सुलझा नहीं कर सकते सी #, जो एक दो-पास संकलक की जरूरत है, आप आगे की जरूरत नहीं का संदर्भ

class A { 
    B b; 
} 

class B { 
    A a; 
} 

क्योंकि संकलक की पहली पास बस सभी प्रतीक परिभाषाओं को चुनता है। जब संकलक अपना दूसरा पास बनाता है, तो यह कह सकता है "मुझे पता है बी बी एक वर्ग है क्योंकि मैंने अपने पहले पास की परिभाषा देखी है"।

+2

+1। – Brian

+0

'जीसीसी' कितने पास का उपयोग करता है? – Lazer

+0

@Lazer: मुझे जीसीसी के लिए विशिष्ट जानकारी नहीं है, लेकिन अधिकांश आधुनिक सी और सी ++ कंपाइलर्स एकाधिक पास का उपयोग करते हैं। वे केवल वास्तविक स्रोत कोड पर एक पास करते हैं और इसे किसी प्रकार के आंतरिक प्रतिनिधित्व में परिवर्तित करते हैं। फिर कोड कोडिंग पास से पहले इस आंतरिक प्रतिनिधित्व पर एक या (आमतौर पर) अधिक अनुकूलन पास होता है। – Ferruccio

7

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

class A { 
    B m_b; 
    C* m_ptrC; 
}; 

इस वर्ग के लिए, आप बी की परिभाषा (आकार की जरूरत) और केवल सी की घोषणा (संकेत आकार तय कर दी है) की जरूरत है। आपको केवल बी के शीर्षलेख को शामिल करने की आवश्यकता है, सी में से एक नहीं। सी की अगली घोषणा पर्याप्त है।

ए।ज:

#ifndef A_H 
#define A_H 

#include <b.h> 
class C; 

class A 
{ 
    B m_b; 
    C* m_ptrC; 
} 
#endif 

ग के आगे घोषणा आप c.h को पार्स जब भी आप ए.एच. शामिल की बचत होती है (बजाय c.h जो भी संभव है सहित) एक बड़ी परियोजना के पार, यह बहुत संकलन समय बचा सकता है। एक और लाभ यह है कि, सीएच में परिवर्तन इस मामले में एक के लिए एक recompile ट्रिगर नहीं है। मुझे नहीं पता कि संकलक इसे पहचानता है अगर आप इसे घोषित करने के बजाय c.h शामिल करते हैं।

अधिक जानकारी के लिए, पिंपल-मुहावरे को समझने का प्रयास करें (बस इसके लिए Google। आपको बहुत सारी हिट मिलेंगी)।

बेशक - एक सीपीपी में यदि आप वास्तव में सी के लिए कुछ करते हैं (उदा। M_ptrC-> जोड़ें()), तो आपको c.h शामिल करना होगा। लेकिन a.cpp केवल एक बार पढ़ा जाता है जहां हेडर फ़ाइल को बड़ी संख्या में कक्षाओं के लिए एन एन पढ़ा जाता है जो अक्सर बड़ी परियोजनाओं में उपयोग किया जाता है।

आगे की घोषणा सर्कुलर निर्भरताओं के लिए भी अनुमति देती है। उदाहरण:

class B; 

class A { 
B* m_ptrB; 
} 

class B { 
A* m_ptrA; 
} 

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

अतिरिक्त जानकारी के लिए: C++ FAQ

परिपत्र निर्भरता के बारे में टिप्पणी के लिए धन्यवाद, मैं बस उन्हें भूल गया।

+0

+1 किसी कारण को आगे घोषित करने के कारण का उल्लेख करने के लिए +1 ... – rubenvb

+0

संकलक-दक्षता उपयोग वैध है, लेकिन मुझे लगता है कि आगे संदर्भों के उद्देश्य के बारे में सोचते समय परिपत्र संदर्भ उपयोग एक बेहतर प्रारंभिक बिंदु है। – Brian