2016-10-09 7 views
5

मेरे पास पशु नामक आधार वर्ग है, और एक कुत्ता और एक बिल्ली जो पशु से प्राप्त होती है। और कुत्ते और बिल्ली से कुत्ते की बिल्ली, में कुत्ते के नाम से जाने वाली एक बहुराष्ट्रीय कक्षा जिसे मैंने नींद कहा है। जब मैं डॉगकैट से उस विधि का उपयोग करना चाहता हूं, तो मुझे त्रुटि मिलती है "डॉग कैट :: नींद" संदिग्ध है, मैं समस्या को समझता हूं, लेकिन मैंने एक पुस्तक में पढ़ा है कि यह संभव होना चाहिए, जब आप नींद को आभासी घोषित करते हैं - लेकिन यह काम नहीं करता।बहुसंख्यक के लिए संदिग्ध कामकाज?

क्या यह संभव नहीं है कि पुस्तक गलत है या कोई कामकाज है?

class Animal 
{ 
public: 
    Animal(){} 

    virtual void sleep() 
    { 
     cout << "zzzzzzzzz" << endl; 
    } 
    virtual void eat() = 0; 

}; 

class Dog: public Animal 
{ 
protected: 
    Dog(){} 

    virtual void eat() override 
    { 
     cout << "eats dogfood" << endl; 
    } 
}; 

class Cat :public Animal 
{ 
public: 
    Cat(){} 
    virtual void eat() override 
    { 
     cout << "eats catfood" << endl; 
    } 
}; 

class DogCat : public Dog, public Cat 
{ 
public: 
    DogCat(){} 
    using Dog::eat; 

}; 

int main(int argc, char** argv) { 
    DogCat *DC = new DogCat(); 
    DC->sleep();//Error 
} 
+0

आप कितने प्रकार के जानवरों को जानते हैं कि बिल्ली और कुत्ते दोनों हैं? – Peter

+0

आईएमएचओ हीरा की समस्या के अधिकांश मामलों में खराब वर्ग डिजाइन का संकेत मिलता है। और आपका मामला निश्चित रूप से उस श्रेणी में पड़ता है। – user463035818

उत्तर

6

का उपयोग करना चाहिए आप diamond problem

enter image description here

"हीरे समस्या" है (कभी कभी "मौत के घातक हीरा के रूप में भेजा "[4]) एक अस्पष्टता है जो तब उत्पन्न होती है जब दो वर्ग बी और सी ए से प्राप्त होते हैं, और कक्षा डी उत्तराधिकारी होते हैं बी और सी दोनों से हैं। यदि बी और सी में कोई विधि है, तो डी ओवरराइड हो गया है, और डी इसे ओवरराइड नहीं करता है, तो विधि का कौन सा संस्करण डी प्राप्त करता है: बी का, या सी का?

तो। अब आपके पास ए के दो उदाहरण हैं। यह समाधान क्या है? आप दो है:

  1. subclases में से एक में नींद आपरेशन परिभाषित करें और यह कहते हैं:
class Cat :public Animal 
{ 
    public: 
     Cat(){} 
     virtual void eat() override 
     { 
      cout << "eats catfood" << endl; 
     } 

     void sleep() 
     { 
      Animal::sleep(); 
     } 
}; 

int main(int argc, char** argv) { 
    DogCat *DC = new DogCat(); 
    DC->Cat::sleep(); 
} 
  1. आभासी विरासत उपयोग @Asesh का कहना है की तरह जवाब। समस्या आम तरीका है()। आपको इसे ओवरराइड करना होगा।
+2

आप' बिल्ली :: नींद 'को हटा सकते हैं लेकिन' बिल्ली :: नींद 'को कॉल करके' डॉग कैट :: नींद 'लागू कर सकते हैं जो' बिल्ली :: नींद 'को स्वाभाविक रूप से' बिल्ली ' रास्ता – Franck

3

आप वर्चुअल विरासत

class Animal 
{ 
public: 
    Animal(){} 

    virtual void sleep() 
    { 
     cout << "zzzzzzzzz" << endl; 
    } 
    virtual void eat() = 0; 

}; 

class Dog: virtual public Animal 
{ 
protected: 
    Dog(){} 

    virtual void eat() override 
    { 
     cout << "eats dogfood" << endl; 
    } 
}; 

class Cat : virtual public Animal 
{ 
public: 
    Cat(){} 
    virtual void eat() override 
    { 
     cout << "eats catfood" << endl; 
    } 
}; 

class DogCat : public Dog, public Cat 
{ 
public: 
    DogCat(){} 
    using Dog::eat; 

}; 

int main(int argc, char** argv) { 
    DogCat *DC = new DogCat(); 
    DC->sleep();//Error 
} 
+2

यह सही उत्तर है। हालांकि, ओपी के लिए हीरा की समस्या को समझने के लिए थोड़ा आगे विस्तार करना अच्छा होगा और क्यों वह अस्पष्टता (यानी कई पशु उदाहरण) और आपके आभासी विरासत समाधान को हल करता है। – Christophe

+0

@ क्रिस्टोफ़े यह अभी भी संकलित नहीं है: http://coliru.stacked-crooked.com/a/07dafb58241bc191 – xinaiz

+0

यह नींद के लिए काम करता है लेकिन मुझे इसे काम करने के लिए डॉग कैट में खाने को ओवरराइड करना पड़ा, यह कहा गया, वर्चुअल ओवरराइड कार्य "पशु :: खाने" अस्पष्ट और अस्पष्ट विरासत है 'शून्य पशु :: खाने (शून्य)' – Niklas

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