سلام!

در جلسات قبل با مفهوم ارث بری آشنا شدیم. حالا می خواهیم با مفهوم ارث بری چند گانه آشنا شویم.

یک هاورکرافت را در نظر بگیرید. این وسیله هم یک وسیله ی نقلیه ی زمینی است و هم یک وسیله ی نقلیه ی آبی. پس ویژگی های این دو را به ارث می برد. در واقع دو کلاس پایه برای هاورکرافت وجود دارد. کد آن شبیه کد زیر می شود؛

class HoverCraft : public LandVehicle , public WaterVehicle;

این نوع ارث بری، کمی مشکل ساز است. بنابراین باید هنگام استفاده از آن حواستان را جمع کنید. یکی از مشکلات آن، وجود دو تابع یا متغیّر هم نام در کلاس های پایه است. به عنوان مثال دستگاه کپی را در نظر بگیرید. این دستگاه تمامی ویژگی های یک دستگاه پرینتر و یک دستگاه اسکنر را به ارث می برد. مشکلی که پیش می آید این است که هر دوی این دستگاه ها (پرینتر و اسکنر) یک کد شناسایی (id) دارند! کد این دو دستگاه را در کد زیر مشاهده کنید.

#include <iostream>
#include <string>

using namespace std;

class Scanner{
    private:
        int _id;
        string _scanned;
    public:
        
        Scanner( int id = 0, string scanned = "" ) : _id( id ) , _scanned( scanned) {}

        int id();
        string scanned();

        void setID( int = 0 );
        void scan();

};

int Scanner::id(){
    return this->_id;
}

string Scanner::scanned(){
    return this->_scanned;
}

void Scanner::setID( int id ){
    this->_id = id;
}

void Scanner::scan(){
    cin >> _scanned;
}

class Printer{
    private:
        int _id;
        string _text;
    public:
        
        Printer( int id = 0, string text = "" ) : _id( id ) , _text( text ) {}

        int id();
        string text();

        void setID( int = 0 );
        void setText( string = "" );
        
        void print( string = "" );

};

int Printer::id(){
    return this->_id;
}

string Printer::text(){
    return this->_text;
}

void Printer::setID( int id ){
    this->_id = id;
}

void Printer::setText( string text ){
    this->_text = text;
}

void Printer::print( string text ){
    if (text == "")
        cout << this->text();
    else cout << text;
}

int main(){
    return 0;
}

حالا یک Copier می سازیم و id آن را درخواست می کنیم (مانند کد زیر).

#include <iostream>
#include <string>

using namespace std;

class Scanner{
    private:
        int _id;
        string _scanned;
    public:
        
        Scanner( int id = 0, string scanned = "" ) : _id( id ) , _scanned( scanned) {}

        int id();
        string scanned();

        void setID( int = 0 );
        void scan();

};

int Scanner::id(){
    return this->_id;
}

string Scanner::scanned(){
    return this->_scanned;
}

void Scanner::setID( int id ){
    this->_id = id;
}

void Scanner::scan(){
    cin >> _scanned;
}

class Printer{
    private:
        int _id;
        string _text;
    public:
        
        Printer( int id = 0, string text = "" ) : _id( id ) , _text( text ) {}

        int id();
        string text();

        void setID( int = 0 );
        void setText( string = "" );
        
        void print( string = "" );

};

int Printer::id(){
    return this->_id;
}

string Printer::text(){
    return this->_text;
}

void Printer::setID( int id ){
    this->_id = id;
}

void Printer::setText( string text ){
    this->_text = text;
}

void Printer::print( string text ){
    if (text == "")
        cout << this->text();
    else cout << text;
}

class Copier : public Scanner , public Printer{
    public:
        
        Copier( int scannerID = 0, int printerID = 0 ) : Scanner( scannerID ) , Printer( printerID ) {}
};

int main(){
    Copier copier( 15, 64 );
    cout << copier.id() << endl;
    return 0;
}

همان طور که می بینید error می دهد. راه حل آن، مشخّص کردن کلاس مورد نظر است. یعنی به جای این که بنویسیم

copier.id();

می نویسیم

copier.Printer::id();

این یکی از مشکلات استفاده از ارث بری چند گانه بود. استفاده از ارث بری چند گانه وقتی که تعداد زیادی کلاس پایه دارید، کار خطرناکی است.

فعلا حرف دیگری باقی نمانده است.

موفق باشید!