علی
علی
خواندن ۲ دقیقه·۵ سال پیش

چند نکته در باب ارث بری در C++

همان طور که می دانید اگر از کلاسی ارث برده شود، توابع غیر خصوصی آن نیز در کلاس فرزند ارث برده شده و رفتارشان حفظ می شود. بدیهی است ممکن است که مواردی نیاز باشد تا فرزندان رفتار متفاوتی نسبت به کلاس پدر داشته باشند. در این مورد باید تابع را بازنویسی کنیم. اما حالتی نیز ممکن است که رخ دهد که فرزند اصل رفتار پدر را در کنار رفتاری از خودش نیاز داشته باشد. به سه کلاس زیر که به صورت سریالی از هم ارث برده اند توجه کنید:


class A{ protected: int getVal()const { return 1; } };


class B :public A{ protected: int getVal()const { return A::getVal()|2; } };


class C : public B{ public: int getVal()const { return 4 | B::getVal(); } };

همچنان که ملاحظه می کنید در هر کلاس وقتی تابع getVal فراخوانی می شود، با استفاده از عملگر :: می توان رفتار تابع پدر را نیز اجرا کرد. مثلا getVal کلاس B رفتار خودش و پدرش را اجرا می کند و getVal کلاس C رفتار خودش، پدرش و پدر بزرگش را نیز اجرا می کند.

حال تصور کنید که کلاس پدر نیاز به فراخوانی تابعی دارد که کلاس های فرزند باید آن را پیاده سازی کنند! در این صورت باید چه کرد؟

کلاس های زیر را در نظر بگیرید:

class A{ protected: int getVal()const=0; int howMuch()const {getVal();} };


class B :public A{ protected: int getVal()const { return 2; } };


int main(int argc, char *argv[]){ A a; int v = a.howMuch(); // v contains value 2 }

همان طور که ملاحظه می کنید، کلاس A دارای یک تابع pure virtual است که توسط یکی دیگر از توابع اش فراخوانی شده است ولی پیاده سازی آن در کلاس فرزند یعنی B صورت گرفته است. این کار درست مانند این آن که کلاس A رفتاری را از فرزندش به ارث برده است!!

پس به طور خلاصه می توان گفت:

"هرگاه بخواهیم در یک کلاس رفتاری را فرزندانمان نیز داشته باشند باید ارث بری کنیم (یه چیز بدیهی هست که فرزندان ژن پدر و مادر را داشته باشند) ولی اگر به طور برعکس بخواهیم کاری را ما الان انجام بدهیم که بعدا فرزندانمان پیاده اش می کنند(!!!) باید تابع را به صورت pure virtual پیاده سازی کنیم." مطلب اخیر مثل آن است که پدر و مادر از فرزند ارث ببرند!!

cارث بریبرنامه نویسی
دانشجوی دکتری- دانشگاه بازل
شاید از این پست‌ها خوشتان بیاید