2011-03-23 18 views
6

मुझे QObject की वजह से कई विरासत के बारे में QT के साथ समस्या हो रही है। मुझे पता है कि बहुत से अन्य लोगों में एक ही समस्या है लेकिन मुझे नहीं पता कि मुझे इसे कैसे ठीक करना चाहिए।क्यूटी एकाधिक विरासत और संकेत

class NavigatableItem : public QObject 
{ 
    Q_OBJECT 

    signals: 
     void deselected(); 
     void selected(); 
     void activated(); 
}; 

class Button : public NavigatableItem, public QToolButton 
{ 
    Q_OBJECT 

    ... 
} 

class MainMenuOption : public Button 
{ 
    Q_OBJECT 

    ... 
} 

जब मैं ऐसा करते हैं

MainMenuOption* messages = new MainMenuOption(); 
connect(messages, SIGNAL(selected()), SLOT(onMenuOptionSelected())) 

मैं त्रुटि मिल जाएगा:

QObject' is an ambiguous base of 'MainMenuOption'

कारण है कि मैं क्योंकि संकेतों के QObject से NavigatableItem enherit करते हैं। क्या इसे करने का कोई तरीका है?

संपादित करें:

प्रत्येक inheritence घोषणा करने के लिए आभासी जोड़ा जा रहा है, अभी भी मुझे एक ही त्रुटि देता है:

class NavigatableItem : public virtual QObject 

class Button : public virtual NavigatableItem, public virtual QToolButton 

class MainMenuOption : public virtual Button 

यहां तक ​​कि एक 'स्वच्छ सब', 'चलाने qmake' और 'निर्माण' सभी के बाद ।

+5

आप एक से अधिक QObject से विरासत नहीं कर सकते उपवर्गों। उनमें से केवल एक QObject हो सकता है, और यह सूची में पहला होना चाहिए। –

+1

उन 'moc_ * ',' * .obj' फ़ाइलों को हटाने का प्रयास करें और सभी को पुनर्निर्माण करें .. – liaK

+0

अद्यतन प्रश्न देखें। पुनर्निर्माण ने इसे ठीक नहीं किया। – RvdK

उत्तर

8

यह थोड़ा अधिक कोड की आवश्यकता है, लेकिन क्या मैं अतीत में किया है एक शुद्ध उनमें से एक (इस मामले में अपने NavigatableItem) बनाते हैं वर्चुअल क्लास, यानी इंटरफ़ेस। "सिग्नल" मैक्रो का उपयोग करने के बजाय, उन्हें शुद्ध वर्चुअल संरक्षित फ़ंक्शन बनाएं। फिर अपने QObject-derived क्लास के साथ-साथ इंटरफ़ेस से गुणा करें- और विधियों को कार्यान्वित करें।

मुझे पता है कि यह कुछ हद तक विवादास्पद है, लेकिन कई लागतों पर कई कार्यान्वयन विरासत से परहेज करने से कई समस्याएं और भ्रम हल हो जाता है। Google C++ Style Guidelines इसकी अनुशंसा करते हैं, और मुझे लगता है कि यह अच्छी सलाह है।

class NavigatableItemInterface 
{ 
    // Don't forget the virtual destructor! 
    protected: 
     virtual void deselected() = 0; 
     virtual void selected() = 0; 
     virtual void activated() = 0; 
}; 

class Button : public NavigatableItemInterface, public QToolButton 
{ 
    Q_OBJECT 
    ... 
    signals: 
     virtual void deselected(); 
     ... 
} 
+0

धन्यवाद डेव, यही वह है जो मैंने किया था इसलिए मैं कम से कम परियोजना का निर्माण कर सकता था। हालांकि एक तरफ प्रभाव यह है कि यदि मेरे पास एक टेक्स्टेंट्री ऑब्जेक्ट है जिसे NavigatableItem होना आवश्यक है, तो मुझे प्रत्येक अचयनित/चयनित और सक्रिय सिग्नल को फिर से परिभाषित करना होगा। – RvdK

+2

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

1

आभासी विरासत का उपयोग करें, उदा।

class X : public virtual Y 
{ 
}; 

class Z : public virtual Y 
{ 
}; 

class A : public virtual X, public virtual Z 
{ 
}; 

केवल आधार वर्ग की एक प्रति होगा वाई

+0

मैंने सभी विरासत घोषणाओं में आभासी जोड़ा लेकिन यह अभी भी मुझे एक ही त्रुटि दे दी। – RvdK

+1

चलकर एमओसी-फाइलों को पुन: उत्पन्न करने का प्रयास करें: विकृत करें; qmake; बनाना। – Tobias

+0

अद्यतन प्रश्न देखें। आभासी और पुनर्निर्माण जोड़ने से इसे ठीक नहीं किया गया। – RvdK

0

आपको वर्चुअल विरासत का उपयोग करना चाहिए।

http://en.allexperts.com/q/C-1040/virtual-inheritance.htm

लगता है जैसे आप हीरा समस्या का सामना कर रहे हैं, यह भी देखें:

http://www.cprogramming.com/tutorial/virtual_inheritance.html

इसे इस तरह कार्य करें:

class NavigatableItem : public virtual QObject 
class Button : public virtual NavigatableItem, public virtual QToolButton 
class MainMenuOption : public Button 
संबंधित मुद्दे