2010-01-27 8 views
8

मैं एक सदस्यसी ++ में सह-निर्भर वर्गों से निपटने का सबसे अच्छा तरीका क्या है?

class foo 
{ 
    bar m_bar; 
}; 

अब मान लीजिए बार foo का मालिक है कि यह

class bar 
{ 
    foo * m_pfoo; 
} 

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

class bar; 

अब हल जोड़ने, यहाँ समस्या है - जब हेडर फाइल लेखन, प्रत्येक हैडर अन्य पर निर्भर करता है: foo.h bar.h में परिभाषाओं की जरूरत है और विपरीतता से। इससे निपटने का सही तरीका क्या है?

उत्तर

23

आपको हेडर से सभी सदस्य पहुंच और अपनी स्रोत फ़ाइलों में स्थानांतरित करने की आवश्यकता है।

इस तरह, आप शीर्ष लेख में अपनी कक्षाओं की घोषणा अग्रेषित कर सकते हैं, और उन्हें foo में परिभाषित:

// foo.h 
class bar; 

class foo { 
    bar * m_pbar; 
} 

// bar.h 
class foo; 
class bar { 
    foo * parent; 
} 

है कि आप काम करने के लिए अनुमति देगा - तुम सिर्फ परिभाषाओं कि में सदस्य जानकारी की आवश्यकता नहीं रख सकते हैं अपने हेडर - इसे .cpp फ़ाइल में ले जाएं। .cpp फ़ाइलों में foo.h और bar.h दोनों शामिल हो सकते हैं:

// Foo.cpp 
#include "foo.h" 
#Include "bar.h" 

void foo::some_method() { 
    this->m_pbar->do_something(); // Legal, now, since both headers have been included 
} 
+0

यह मुझे आवश्यक चीज़ों के लिए सबसे अच्छा विकल्प लगता है। –

+1

अब यह समाधान कैसे काम करता है यदि आपके कोडपेन्डेंट क्लास टेम्पलेट किए गए हैं, और इसलिए हेडर और सीपीपी फ़ाइलों में विभाजित नहीं किया जा सकता है? –

0

जहां तक ​​मुझे पता है, ऐसा करने का एकमात्र असली तरीका पॉइंटर्स का उपयोग कर रहा है क्योंकि उन्हें अनुवाद इकाई (.cpp) तक कक्षा परिभाषा की आवश्यकता नहीं होती है, इस मामले में दोनों वर्गों को ठीक से परिभाषित किया जाएगा।

2

मुझे लगता है कि कोई भी सदस्य बिना किसी सदस्य के अमूर्त इंटरफ़ेस कक्षाएं बनाना है। फिर उन इंटरफेस कक्षाओं से fcl और बार subclass।

जैसे:

class FooInterface 
{ 
    // methods here 
} 

class BarInterface 
{ 
    // methods here 
} 

class Foo : public FooInterface 
{ 
    BarInterface *pBar; 
} 

class Bar : public BarInterface 
{ 
    FooInterface *pFoo; 
} 

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

1

में आपका उदाहरण, foobar पर निर्भर करता है (क्योंकि इसमें वास्तविक bar ऑब्जेक्ट है), लेकिन barfoo पर निर्भर नहीं है (क्योंकि इसमें केवल foo * है)। अब barfoo पर एक प्रकार का नाम होने पर निर्भर करता है, इसलिए bar.h को नाम की अगली घोषणा की आवश्यकता है: class foo;foobar पर निर्भर करता है, तो foo.h शामिल करना चाहिए #include "bar.h"

आप वर्गों है कि सीधे सी में एक दूसरे पर निर्भर नहीं हो सकता ++; यह बस काम नहीं करता है। आपको कक्षाओं को कम करने की आवश्यकता है जैसे कि केवल आपके मौजूदा उदाहरण की तरह अन्य मौजूदा पर निर्भर करता है। एकमात्र चीजें जो प्रत्यक्ष निर्भरता पैदा करती हैं वे कक्षा को बेस क्लास या फ़ील्ड के रूप में उपयोग कर रही हैं; कोई अन्य उपयोग सिर्फ एक अप्रत्यक्ष निर्भरता बनाता है, जो आम तौर पर एक समस्या नहीं है।

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