تکه کدهای چالش برانگیز همراه با توضیحات فنی
کد زیر را بررسی نمائید درصورت داشتن خطا در کد زیر، آنها را در قسمت دیدگاه ارسال نمائید.
statement1:
این خط اشتباه می باشد، چون در ارجاع ها نباید مقدار عددی ثابت را به آنها اعمال کنیم ودر این خط متغیر a بعد از تبدیل شدن به یک مقدار int در واقع یک مقدار می باشد نه یک متغیر.
statement2:
این خط هم شبیه خط کد بالا یک مقدار را از تابع برمیگرداند و به ارجاع اعمال میکند که طبق قانون ارجاع ها در سی پلاس پلاس نمیتوان یک مقدار ثابت به ارجاع اعمال کرد.
statement3:
ظاهرا این خط کد هم یک مقدار ثابت به ارجاع اعمال می نماید که باید طبق قانون سی پلاس پلاس خطا بدهد ولی نکته این خط کد این است که متغیر ارجاع به صورت ثابت یا const تعریف شده است و به همین علت می توان به آن یک مقدار ثابت را اعمال کرد.
خروجی کد زیر چیست؟
نکات کلی:
کلاس های OutA و OutB ساختار چندریختی یا polymorphism دارند چون فانکشن های داخل کلاس OutA به صورت مجازی تعریف شده اند.به تابع updateString() دقت نمائید.
کلاس های A و B ساختار چندریختی یا polymorphism ندارند چون فانکشن های داخل کلاس A و به صورت مجازی تعریف نشده اند.
توضیح خطوط تابع main:
خط 70: در این خط یک آبجکت از کلاس A ساخته میشود که در داخل هدر کلاس A یک آبجکت از کلاس OutA وجود دارد. پس قبل ازاینکه سازنده کلاس A ساخته شود سازنده کلاس OutA ساخته خواهد شد ، چون یک شی از کلاس OutA در داخل کلاس A وجود دارد.نکته جالب این است که اول سازنده کلاس OutA و بعداز آن سازنده کلاس A اجرا خواهد شد چون هر شی ای در هدر یک کلاس باشد قبل اجرای سازنده کلاس باید ساخته شود.این اصل در ساختار برنامه نویسی سی پلاس پلاس می باشد.
مقدار شی a از مقدار کلاس B مقدار دهی شده است.در زمان ساخت شی کلاس B ، هم یک شی از کلاس OutB وجود دارد پس اول سازنده کلاس OutB ساخته می شود بعد ازآن سازنده کلاس B اجرا خواهد شد. دقت داشته باشید که نابود گر کلاس Bبعد از این خط اجرا خواهد شد سپس کاراکتر s را چاپ خواهد کرد و کاراکتر را یک مرتبه کاهش خواهد داد و کاراکتر r خواهد شد.
خط 71: در این قسمت یک کاراکتر با متغییر s1 به تابع ارسال میکنیم.و درداخل تابع getOutput چاپ می شود و آدرس شی ای از کلاس OutA را برمیگرداند. توسط تابع reinterpret_cast مقدار شی OutA به آدرس OutB تبدیل می شود.
خط 72: در این خط از کد فقط یک رشته برگردانده میشود که آن رشته باید چاپ شود. حال نکته این خط چیست؟ در نکات بالا گفته شد که کلاس OutA و OutB به صورت چندریختی نوشته شده است. برای اطلاعات بیشتر، پوینتر ها در چندریختی مطالعه شود، ولی در اینجا اشاره کوتاهی خواهیم کرد: در زمانی که کلاس چندریختی داریم یک پوینتر توسط یک کلاس دیگر مثلا OutA مقداردهی شود ،توابع کلاس OutA اجرا خواهد شد. شی o1 که از کلاس OutB می باشد و با کلاس OutَA مقداردهی شده است پس توابع کلاس OutA را اجرا خواهد کرد چون مقدار دهی توسط این کلاس صورت گرفته است.حالا داخل تابع getString از کلاس OutA اجرا خواهد شد و مقدار n را برخواهد گرداند.(امیدوارم پیچیده نشده باشه)
خط 74: این خط کد شبیه خط کد 70 می باشد بااین تفاوت که شی ساخته شده یک پوینتر می باشد و مقدار آن توسط خود کلاس B صورت گرفته است.
خط 75: این خط کد برعکس خط 71 می باشد.در خط 76 خواهم گفت برعکس به چه منظور…
خط 76: پوینتر o2 تابع getString را فراخوانی میکند که در داخل این تابع یک تابع دیگر به نام updateString فراخوانی میشود ولی کدام تابع از کدام کلاس…؟
بخاطر قوانین چندریختی، تابع updateString از کلاس OutB در داخل getString اجرا خواهد شد و به همین دلیل کاراکتر o که در داخل متغیر msg می باشد به خروجی برگردانده خواهد شد. تابع getString به عنوان تابعی عمومی در parent می باشد که کلاس child آن را به ارث گرفته است.
در خط 77 هم دستراکتر این کلاس فراخوانی خواهد شد که متغیر m که حاوی کاراکتر r می باشد را چاپ خواهد کرد.
خروجی برنامه: senior
نکته مهم: همیشه در ساختار شی گرایی نابودگرها را به صورت مجازی تعریف نمائید. اتفاقی که در این تکه کد صورت نگرفته است ولی بهتر است که مجازی باشد.برای مطالعه بیشتر نابودگرهای مجازی را مطالعه نمائید.
تفاوت انتصاب یک آرایه با آدرس آرایه به اشاره گر
قبل از توضیح عکس بالا، یک نکته ساده باید گفته بشه.
- انتساب آرایه ای از کاراکتر ها(رشته) به یک اشاره گر از نوع char امکان پذیر می باشد، همانند خط ششم.
- انتساب آدرس آرایه ای از کاراکتر ها(رشته) به یک اشاره گر از نوع char با روش بالا امکان پذیر نمی باشد، همانند خط هفتم. چرا؟؟
علت: سمت راست مساوی یک مقدار سمت راستی یا اصطلاحا rvalue از نوع اشاره گر به کاراکتر ده تایی می باشد ولی سمت چپ مساوی یک اشاره گر از نوع کاراکتر می باشد.
- انتساب آرایه ای از کاراکتر ها(رشته) به یک اشاره گر از نوع void امکان پذیر می باشد، همانند خط نهم.
- انتساب آدرس آرایه ای از کاراکتر ها(رشته) به یک اشاره گر از نوع void امکان پذیر می باشد، همانند خط دهم. چرا؟
علت: دلیل اینکه آدرس یک آرایه را می توان به یک اشاره گر منتسب کرد این است که اشاره گر از نوع void یک اشاره گری است که به هر نوع آدرسی می توان آن را اعمال کرد، این یک قانون در اشاره گر ها می باشد.
توضیحات درمورد انتساب آرایه یا آدرس آرایه به یک اشاره گر از نوع void:
با بررسی حافظه این متغیرها و مقادیر داخل آنها مشخص خواهد شد که چهار نکته بالا صحیح می باشد.
امکانات مورد استفاده شده: کامپایلر mingw، سیستم عامل ویندوز و IDE Qt cretor می باشد.
تصویر پائین، تمام جزئیات مرتبط به چالش مورد نظر را به وضوح بیان می کند.




