PDA

نسخه کامل مشاهده نسخه کامل : عدم امکان ارث بری از ساختارها



Life24
27-07-2015, 01:19
سلام بر اساتید. :n16:

چرا نزاشتند از ساختار ها ارث بری کنیم؟ چه دلیل فنی داشتند؟

_H2_
21-08-2015, 22:27
سلام
مدل حافظه و عدم اطلاع محیط runtime از type ساختارها...
توضیح کمی بیشتر...

=====
مشکل مدل حافظه (وابستگی داده ها به کامپایلر)
الف)
تمام فیلدهای struct ها مستقیم در حافظه پشته قرار میگیرند.

ب)
در حالیکه برای class ها فقط یک اشاره گر در پشته قرار میگیرد و دیتای اصلی بطور شناور در هیپ ذخیره میشود.

ج)
وقتی مشتق/وراثت میگیریم، فیلدهای جدید تعریف میکنید و کلاس جدید بزرگتر میشود.

د)
یک قابلیت مهم در وراثت رابطه is-a است، یعنی شما میتوانید متغییری از کلاس پایه تعریف و بعدا نمونه مشتق را در آن بریزید.

هـ)
تخصیص و جایگیری مقادیر در پشته در زمان کامپایل و توسط کامپایلر صورت میگیرد، برخلاف هیپ که در زمان اجرا برای آن تصمیم گیری میشود.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

Class1 بطور تئوری 1 بایت در هیپ جا میگیرید
Class2 بطور تئوری 2 بایت در هیپ جا میگیرید
متغییر z همواره در یک سیستم 64 بیتی، 8 بایت در حافظه پشته خواهد داشت. (یک اشاره گر)

حجم بایتی Class1 و Class2 تاثیری بر تغییر تعداد بایت های پشته ندارد، کامپایلر برای z در پشته 8 بایت کنار میگذارد حالا z درزمان اجرا null یا new Class1 یا new Class2 باشد تاثیری ندارد.

حالا همه این واقعیت ها را کنار هم بگذارید متوجه میشوید با شرایط جاری امکان وراثت struct ها وجود ندارد.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر همین حالت را برای struct درنظر بگیرید، Struct1 فقط 1 بایت در پشته و Struct2 فقط 2 بایت در پشته لازم دارد پس متوجه میشود که کامپایلر در زمان کامپایل راهی برای رزو حافظه مورد نیاز z ندارد. (مجدد تاکید میکنم این وظیفه کامپایلر است و مانند هیپ نیست)

اصولا اگر بفرض قرار باشد این تفاوت ها مدل حافظه هم برطرف شود دیگر دوساختار struct و class نداشتیم و یکی میشد، همین تفاوت ها این دو را متمایز میسازد.

=====
مشکل بی اطلاعی زمان اجرا از type (وابستگی کد ها به کامپایلر)

الف)
در وراثت شما میتوانید کدهای کلاس پایه را تغییر دهید همان چندریختگی و virtual و...

ب)
در وراثت مجدد قابلیت is-a را داریم که متغیری از کلاس پایه میتواند نمونه ای از مشتق را در خود جای دهد.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

در class ها ما در زمان runtime از type اطلاع داریم.
در واقع همه کلاس های دات نت یک فیلد خاص مخفی اولیه شامل اشاره گری به Type دارند.
در مثال بالا ما دو Func داریم و این runtime (در همان لحظه اجرا به کمک جداولی) است که در مورد اجرای کدام یک تصمیم گیری میشود.

ولی در struct ها محیط runtime هیچ اطلاع اضافه ای از متغییر ها نگاه داشته نمیشود و هیچ راهی برای تصمیم گیری بین اجرای چندریختگی متدها وجود ندارد.
در struct ها فقط کامپایلر از type متغییر آگاه است.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
خطوط فوق شاید شبیه هم باشند ولی از نظر حافظه خیلی متفاوت هستند...
متغییر y هشت بایت در پشته گرفته که اشاره گری به یک اشاره گر 8 بایتی دیگر است و آن اشاره گر دوم به یک بلاک 9 بایتی شامل 8 بایت اشاره گر Type و 1 بایت مقدار x اشاره دارد...

درحالیکه به ازای متغییر z فقط و فقط یک بایت در پشته ذخیره میشود.
طبیعتا باید یک فرقی بین 1 بایت تخصیص حافظه و 25 بایت و شاید بیشتر حافظه باشد!
یکی برای انواع توانایی ها تجهیز شده و دیگری در ساده ترین شکل ممکن رها شده

=====
در واقع هم قسمت Data و هم Code در struct ها وابسته به کامپایلر و زمان کامپایل است و دیتای اضافه ای برای محیط runtime وجود ندارد و البته کاری هم در runtime نیست والبته کمی سرعت و بازدهی بیشتر به شرط درست خرج شدنش بدنبال خواهد داشت.

(((
نکته یا شبه: !
در struct ها فقط کامپایلر از type متغییر آگاه است.
پس GetType روی struct چطور در runtime کار میکند؟
جوابش جالبش باید به عهده خودتان! آتش به اختیار!
)))

شب خوش.