stringtranslate.com

اعزام پویا

در علوم کامپیوتر ، ارسال پویا فرآیند انتخاب اجرای یک عملیات چندشکلی ( روش یا تابع) است که در زمان اجرا فراخوانی شود . معمولاً در زبان‌ها و سیستم‌های برنامه‌نویسی شی‌گرا (OOP) استفاده می‌شود و مشخصه اصلی آن در نظر گرفته می‌شود . [1]

سیستم های شی گرا یک مشکل را به عنوان مجموعه ای از اشیاء متقابل مدل می کنند که عملیاتی را انجام می دهند که با نام ذکر شده است. چند شکلی پدیده ای است که در آن اشیاء تا حدی قابل تعویض، هر یک عملیاتی با نام مشابه اما احتمالاً در رفتار متفاوت را نشان می دهند. به عنوان مثال، یک شی File و یک شی پایگاه داده هر دو دارای یک روش StoreRecord هستند که می تواند برای نوشتن یک رکورد پرسنل در ذخیره سازی استفاده شود. پیاده سازی آنها متفاوت است. یک برنامه یک مرجع به یک شی دارد که ممکن است یک شی File یا یک شی پایگاه داده باشد . این که کدام است ممکن است با تنظیم زمان اجرا مشخص شده باشد، و در این مرحله، برنامه ممکن است نداند یا اهمیتی نداشته باشد. هنگامی که برنامه StoreRecord را روی شیء فراخوانی می کند، چیزی باید انتخاب کند که کدام رفتار اعمال می شود. اگر کسی OOP را به عنوان ارسال پیام به اشیا در نظر بگیرد، در این مثال، برنامه یک پیام StoreRecord را به یک شی از نوع ناشناخته ارسال می کند و آن را به سیستم پشتیبانی زمان اجرا می گذارد تا پیام را به شی مناسب ارسال کند. شیء هر رفتاری را که اجرا می کند اعمال می کند. [2]

ارسال پویا در تضاد با ارسال استاتیک است که در آن اجرای یک عملیات چند شکلی در زمان کامپایل انتخاب می شود . هدف از ارسال پویا به تعویق انداختن انتخاب یک پیاده سازی مناسب تا زمانی است که نوع زمان اجرا یک پارامتر (یا پارامترهای متعدد) مشخص شود.

ارسال دینامیک با اتصال دیرهنگام (همچنین به عنوان اتصال پویا شناخته می شود) متفاوت است . Binding Name یک نام را با یک عملیات مرتبط می کند. یک عملیات چند شکلی چندین اجرا دارد که همگی با یک نام مرتبط هستند. صحافی ها را می توان در زمان کامپایل یا (با صحافی دیرهنگام) در زمان اجرا انجام داد. با ارسال پویا، یک پیاده سازی خاص از یک عملیات در زمان اجرا انتخاب می شود. در حالی که ارسال دینامیک به معنای اتصال دیرهنگام نیست، اتصال دیرهنگام مستلزم ارسال پویا است، زیرا اجرای عملیات با کران دیر تا زمان اجرا مشخص نیست. [ نیازمند منبع ]

اعزام تک و چندگانه

انتخاب نسخه ای از یک روش برای فراخوانی ممکن است بر اساس یک شی واحد یا ترکیبی از اشیاء باشد. اولی تک ارسال نامیده می شود و مستقیماً توسط زبان های شی گرا رایج مانند Smalltalk ، C++ ، Java ، C# ، Objective-C ، Swift ، JavaScript و Python پشتیبانی می شود . در این زبان‌ها و زبان‌های مشابه، می‌توان روشی را برای تقسیم با نحوی فراخوانی کرد

سود سهام . تقسیم ( تقسیم کننده )  # سود سهام / تقسیم کننده

که در آن پارامترها اختیاری هستند. این به عنوان ارسال پیامی به نام divide با مقسوم‌کننده پارامتر به سود در نظر گرفته می‌شود . یک پیاده سازی تنها بر اساس نوع سود تقسیمی (شاید منطقی ، ممیز شناور ، ماتریس )، بدون توجه به نوع یا مقدار مقسوم علیه انتخاب خواهد شد .

در مقابل، برخی از زبان ها روش ها یا توابع را بر اساس ترکیب عملوندها ارسال می کنند. در مورد تقسیم، انواع تقسیم و تقسیم کننده با هم تعیین می کنند که کدام عملیات تقسیم انجام می شود. این به عنوان ارسال چندگانه شناخته می شود . نمونه‌هایی از زبان‌هایی که از ارسال چندگانه پشتیبانی می‌کنند عبارتند از Common Lisp ، Dylan و Julia .

مکانیسم های اعزام پویا

یک زبان ممکن است با مکانیسم‌های مختلف ارسال پویا پیاده‌سازی شود. انتخاب‌های مکانیزم ارسال پویا که توسط یک زبان ارائه می‌شود تا حد زیادی پارادایم‌های برنامه‌نویسی را که در دسترس هستند یا برای استفاده در یک زبان خاص طبیعی‌تر هستند، تغییر می‌دهند.

به طور معمول، در یک زبان تایپ شده، مکانیسم ارسال بر اساس نوع آرگومان ها (که بیشتر بر اساس نوع گیرنده پیام است) انجام می شود. زبان‌هایی با سیستم‌های تایپ ضعیف یا بدون سیستم، اغلب یک جدول اعزام را به عنوان بخشی از داده‌های شی برای هر شیء حمل می‌کنند. این به رفتار نمونه اجازه می دهد زیرا هر نمونه ممکن است یک پیام داده شده را به یک روش جداگانه ترسیم کند.

برخی از زبان ها یک رویکرد ترکیبی ارائه می دهند.

ارسال پویا همیشه هزینه‌ای را به همراه خواهد داشت، بنابراین برخی از زبان‌ها ارسال ثابت را برای روش‌های خاص ارائه می‌دهند.

پیاده سازی C++

C++ از اتصال اولیه استفاده می کند و ارسال پویا و استاتیک را ارائه می دهد. فرم پیش فرض ارسال ثابت است. برای به دست آوردن ارسال پویا، برنامه نویس باید یک متد را مجازی اعلام کند .

کامپایلرهای C++ معمولاً توزیع پویا را با ساختار داده ای به نام جدول تابع مجازی (vtable) پیاده سازی می کنند که نگاشت نام به پیاده سازی را برای یک کلاس معین به عنوان مجموعه ای از اشاره گرهای تابع عضو تعریف می کند. این صرفاً یک جزئیات پیاده سازی است، زیرا در مشخصات C++ به vtable ها اشاره نشده است. نمونه‌هایی از این نوع، یک اشاره‌گر را به این جدول به عنوان بخشی از داده‌های نمونه خود ذخیره می‌کنند، که در صورت استفاده از وراثت چندگانه ، سناریوها را پیچیده می‌کند. از آنجایی که C++ از اتصال دیرهنگام پشتیبانی نمی کند، جدول مجازی در یک شی C++ را نمی توان در زمان اجرا تغییر داد، که مجموعه بالقوه اهداف ارسال را به یک مجموعه محدود انتخاب شده در زمان کامپایل محدود می کند.

بارگذاری بیش از حد نوع باعث ارسال پویا در ++C نمی شود زیرا زبان انواع پارامترهای پیام را بخشی از نام پیام رسمی در نظر می گیرد. این بدان معنی است که نام پیامی که برنامه نویس می بیند، نام رسمی مورد استفاده برای اتصال نیست.

برو، اجرای Rust و Nim

در Go ، Rust و Nim ، از تنوع متنوع تری از اتصال اولیه استفاده می شود. اشاره گرهای Vtable با ارجاعات شیء به عنوان «نشانگرهای چربی» («رابط» در Go، یا «اشیاء صفت» در Rust [3] [4] ) حمل می شوند.

این رابط های پشتیبانی شده را از ساختارهای داده زیرین جدا می کند. هر کتابخانه کامپایل شده برای استفاده صحیح از یک نوع نیازی به دانستن طیف کامل رابط های پشتیبانی شده ندارد، فقط طرح بندی vtable خاصی را که نیاز دارد. کد می تواند رابط های مختلف را به یک قطعه از داده ها به توابع مختلف منتقل کند. این تطبیق پذیری به هزینه داده های اضافی با هر مرجع شی است، که اگر بسیاری از چنین مراجع به طور مداوم ذخیره شوند مشکل ساز است.

اصطلاح اشاره گر چربی به سادگی به یک اشاره گر با اطلاعات مرتبط اضافی اشاره دارد. اطلاعات اضافی ممکن است یک نشانگر vtable برای ارسال پویا باشد که در بالا توضیح داده شد، اما معمولاً اندازه شی مرتبط برای توصیف یک قطعه است . [ نیازمند منبع ]

اجرای اسمال تاک

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

از آنجایی که یک نوع می تواند زنجیره ای از انواع پایه داشته باشد، این جستجو می تواند گران باشد. به نظر می رسد اجرای ساده مکانیزم Smalltalk سربار به طور قابل توجهی بالاتر از C++ داشته باشد و این سربار برای هر پیامی که یک شی دریافت می کند متحمل می شود.

پیاده‌سازی‌های Real Smalltalk اغلب از تکنیکی به نام کش درونی [5] استفاده می‌کنند که ارسال روش را بسیار سریع می‌کند. کش درونی اساساً آدرس روش مقصد قبلی و کلاس شی سایت تماس (یا چندین جفت برای کش چند طرفه) را ذخیره می کند. روش ذخیره‌سازی شده با متداول‌ترین روش هدف (یا فقط کنترل‌کننده خطای حافظه پنهان)، بر اساس انتخابگر روش، مقداردهی اولیه می‌شود. هنگامی که در حین اجرا به سایت فراخوانی متد رسید، فقط آدرس موجود در حافظه پنهان را فراخوانی می کند. (در یک مولد کد پویا، این فراخوانی یک تماس مستقیم است، زیرا آدرس مستقیم توسط منطق از دست دادن حافظه پنهان وصله شده است.) کد پیش درآمد در متد فراخوانی شده، کلاس ذخیره شده در حافظه پنهان را با کلاس شی واقعی مقایسه می کند، و اگر آنها مطابقت ندارند ، برای یافتن متد صحیح در کلاس، به یک کنترل کننده خطای حافظه پنهان منشعب می شود. یک پیاده‌سازی سریع ممکن است چندین ورودی حافظه پنهان داشته باشد و اغلب تنها به چند دستورالعمل نیاز دارد تا در یک خطای کش اولیه اجرا به روش صحیح برسد. مورد رایج یک تطبیق کلاس حافظه پنهان خواهد بود و اجرا فقط در متد ادامه خواهد داشت.

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

از آنجایی که Smalltalk یک زبان انعکاسی است، بسیاری از پیاده‌سازی‌ها اجازه می‌دهند تا اشیاء منفرد را به اشیا با جداول جستجوی متد تولید شده به صورت پویا تغییر دهند. این اجازه می دهد تا رفتار شی را بر اساس هر شی تغییر دهید. دسته کاملی از زبان‌ها که به عنوان زبان‌های مبتنی بر نمونه اولیه شناخته می‌شوند ، از این موضوع رشد کرده‌اند که معروف‌ترین آنها Self و JavaScript هستند . طراحی دقیق ذخیره‌سازی متدهای ارسالی، حتی به زبان‌های مبتنی بر نمونه اولیه اجازه می‌دهد تا روش ارسال با کارایی بالا داشته باشند.

بسیاری دیگر از زبان های تایپ پویا، از جمله Python ، Ruby ، Objective-C و Groovy از رویکردهای مشابه استفاده می کنند.

مثال در پایتون

class  Cat :  def  speak ( self ):  چاپ ( "Meow" )class  Dog :  def  speak ( self ):  چاپ ( "Woof" )def  speak ( pet ):  # به صورت پویا روش صحبت را ارسال می کند  # pet می تواند نمونه ای از گربه یا سگ  حیوان خانگی باشد . صحبت کن ()گربه  =  گربه () صحبت می کند ( گربه ) سگ  =  سگ () صحبت می کند ( سگ )

مثال در C++

#include <iostream> // پت را یک کلاس پایه مجازی انتزاعی کنید کلاس Pet { public : virtual void speak () = 0 ; };       class Dog : public Pet { public : void speak () override { std :: cout << "Woof! \n " ; } }             class Cat : public Pet { public : void speak () override { std :: cout << "Meow! \n " ; } }             // speak() قادر خواهد بود هر چیزی را که از Pet void speak ( Pet & pet ) نشأت می گیرد بپذیرد . صحبت کردن (); }   int main () { Dog fido ; گربه سیمبا ؛ صحبت کردن ( fido ); صحبت کردن ( simba بازگشت 0 ; }         

همچنین ببینید

مراجع

  1. ^ میلتون، اسکات؛ اشمیت، هاینز دبلیو (1994). ارسال پویا در زبان های شی گرا (گزارش فنی). جلد TR-CS-94-02. دانشگاه ملی استرالیا CiteSeerX  10.1.1.33.4292 .
  2. دریزن، کارل؛ هلزل، اورس؛ ویتک، جان (1995). "ارسال پیام در پردازنده های خط لوله". ECOOP'95 — برنامه نویسی شی گرا، نهمین کنفرانس اروپایی، آرهوس، دانمارک، 7 تا 11 آگوست، 1995 . نکات سخنرانی در علوم کامپیوتر. جلد 952. اسپرینگر. CiteSeerX 10.1.1.122.281 . doi :10.1007/3-540-49538-X_13. شابک  3-540-49538-X.
  3. ^ کلابنیک، استیو؛ نیکولز، کارول (2023) [2018]. "17. ویژگی های برنامه نویسی شی گرا". زبان برنامه نویسی Rust (ویرایش 2). سانفرانسیسکو، کالیفرنیا، ایالات متحده: No Starch Press, Inc. صفحات 375-396 [379-384]. شابک 978-1-7185-0310-6. ص 384: اشیاء صفت ارسال پویا را انجام می دهند […] وقتی از اشیاء صفت استفاده می کنیم، Rust باید از ارسال پویا استفاده کند. کامپایلر همه انواعی را که ممکن است با کدی که از اشیاء صفت استفاده می‌کند، نمی‌داند، بنابراین نمی‌داند کدام متد بر روی کدام نوع اجرا شده است. در عوض، در زمان اجرا، Rust از نشانگرهای داخل شیء صفت استفاده می‌کند تا بداند کدام متد را فراخوانی کند. این جستجو هزینه زمان اجرا را متحمل می شود که با ارسال استاتیک رخ نمی دهد. ارسال پویا همچنین مانع از انتخاب کامپایلر می‌شود تا کد یک متد را درون خطی انتخاب کند، که به نوبه خود از برخی بهینه‌سازی‌ها جلوگیری می‌کند.(xxix+1+527+3 صفحه)
  4. «اشیاء صفت». مرجع زنگ . بازیابی شده در 2023-04-27 .
  5. مولر، مارتین (1995). ارسال پیام در زبان های شی گرا با تایپ پویا (پایان نامه کارشناسی ارشد). دانشگاه نیومکزیکو. صفحات 16-17. CiteSeerX 10.1.1.55.1782 . 

در ادامه مطلب