تمام سوالات سوالات بدون پاسخ سوال بپرسید

سلام به دوستان عزیز،
در زبان برنامه نویسی C++ به دو مطلب برخورد کردم که فکر میکنم که درست نفهمیدم. در مورد static_cast
و
dynamic_cast کسی چیزی میدونه؟
چه هستند و چه کاربردی دارن و چه تفاوتی با هم دارن؟

با تشکر

2 پاسخ

سلام همانطور که می دانید تبدیل نوع در cpp به دو دسته کلی ضمنی و صریح تقسیم می شود. اما تبدیل نوع های صریح به چهار شکل هستند:
1. const_cast: برای تبدیل اشاره گر ثابتی که به نوعی تعریف شده به اشاره گر عادی استفاده می شود. 2. static_cast: برای تبدیل نوع هایی که راه مشخصی برای تبدیل آنها وجود دارد. این راه ممکن است توسط کامپایلر تعریف شده باشد یا در کلاس تعریف شود. برای نمونه تبدیل اشاره گر به کلاس فرزند به پدر یا بلعکس یا تبدیل int به float یا تبدیل enum به int و مواردی از این دست. توجه کنیم که در این نوع از تبدیل هیچ بررسی در زمان اجرا انجام نمی شود و تنها کامپایلر درستی آنرا بررسی می کند. پس احتمال خطا در زمان اجرا منتفی نیست.
3. dynamic_cast: همانند static_cast عمل می کند با این تفاوت که عمل تبدیل را با استفاده از RTTI (اطلاعات نوع ها در زمان اجرا) و در زمان اجرا انجام می دهد. بنابراین اگر نوعی قابل تبدیل به نوع خواسته شده نباشد، مقدار null (وقتی نوع مبد‌أ اشاره گر باشد) یا استثناء (در صورتی که نوع مبدأ مرجع باشد) برخواهد گشت. شاید بتوان گفت که این نوع از تبدیل نوع متداول تبدیل در زبان های متداول همچون #C است.
4. reinterpret_cast: این نوع از تبدیل بدون توجه به نوع های مبدأ و مقصد هر نوع تبدیلی را انجام می دهد. معمولاً در جایی که برنامه نویس کاملاً متوجه است که چه کار می کند، از این نوع از تبدیل استفاده می شود. مثلاً حالت هایی را در نظر بگیرید که دو کلاس هیچ ارتباطی از نظر وراثتی با هم نداشته باشند، اما نوع قرار گیری آنها در حافظه دقیقاً مثل هم باشد و برنامه نویس از این حالت با خبر باشد در این صورت می تواند از این تبدیل استفاده کند. باید توجه داشت که هیچ نوع بررسی و کنترل زمان کامپایل و اجرا روی این نوع از تبدیل انجام نمی شود. معمولاً این نوع از تبدیل ها روی platform ها مختلف کار نمی کنند.

پس تفاوت اصلی که میان دو نوع تبدیل static_cast و dynamic_cast وجود دارد، این است که در اولی تبدیل توسط کامپایلر انجام می شود و بررسی های مربوط به آن در زمان کامپایل انجام می شود و در زمان اجرا هیچ نوع بررسی انجام نمی شود. ولی در dynamic_cast عمل تبدیل نوع همانند زبان هایی مثل #C در زمان اجرا و با استفاده از RTTI انجام می شود. پس این نوع در زمان کامپایل انجام نمی شود. شاید استفاده از dynamic_cast بهتر باشد. اینطور نیست؟!

1

سلام دوست عزیز، بسیار ممنون از وقتی که گذاشتی.
نیمی از سوال شما و نیمی از سوال ir01‌ جواب نیاز من رو داد. با تشکر از به اشتراک گذاشتن دانشتان :)

(10 مارس '12, 23:43) _Ant Eater_

سلام
همونطور که می‌دونی دو نوع تبدیل نوع کلی داریم:

  1. تبدیل نوع صریح
  2. تبدیل نوع ضمنی

در تبدیل نوع صریح هر نوع اشاره‌گری را می‌توان به هر نوع اشاره‌گر دیگر تبدیل کرد و اشتباهات تبدیل نوع با به وجود آمدن خطا در زمان اجرا مشخص می‌شد. برای کمتر شدن خطاهای زمان اجرا چهار عملگر زیر ارائه شده است:

dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)

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

class CHamcodiBase { };
class CHamcodiDerived: public CHamcodiBase { };

CHamcodiBase hb; CHamcodiBase* phb;
CHamcodiDerived hd; CHamcodiDerived* phd;

phb = dynamic_cast<CHamcodiBase*>(&hd);     // correct: derived2base
phd = dynamic_cast<CHamcodiDerived*>(&hb);  // wrong: base2derived

عملگر static__cast به سخت گیری dynamic_cast نیست. فقط کافی است که شیء حاصل از تبدیل نوع با شیء اولیه سازگار باشد. مثلا می‌توان یک اشاره‌گر به کلاس پایه را به یک اشاره‌گر به کلاس فرزند آن تبدیل کرد. به طور مثال:

class CHamcodiBase { };
class CHamcodiDerived: public CHamcodiBase { };

CHamcodiBase * a = new CHamcodiBase;
CHamcodiDerived * b = static_cast<CHamcodiDerived*>(a);

توضیحات تکمیلی در این صفحه‌ی سایت cplusplus.com وجود داره

1

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

(10 مارس '12, 23:41) _Ant Eater_
toggle preview



آموزش زبان برنامه نویسی C#
آموزش jquery
آموزش برنامه نویسی
آموزش طراحی وبسایت
آموزش مدیریت وبسایت
آموزش جاوا Java
آموزش پایتون Python
آموزش سی شارپ C#‎
آموزش HTML و CSS
آموزش JavaScript جاوااسکریپت
آموزش jQuery جی کوئری
آموزش ساخت ربات تلگرام
آموزش برنامه‌نویسی PHP
آموزش برنامه‌نویسی اندروید
● آموزش‌های رایگان

سوالات مرتبط

راهنمای استفاده از ویرایشگر
  • *ایتالیک*‌ یا __ایتالیک__
  • **ضخیم** یا __ضخیم__
  • آدرس:[متن](http://url.com/ "عنوان")
  • عکس?![alt متن](/path/img.jpg "عنوان")
  • لیست عددی: 1. Foo 2. Bar
  • برای رفتن به خط بعد، هر جا مایلید که خط جدید شروع شود دو کاراکتر فاصله (space) قرار دهید
  • تگ‌های ساده HTML هم پشتیبانی می‌شوند

تگها:
  • ×55
  • ×32
  • پرسیده شده: 09 مارس '12, 19:27
  • بازدید: 5,065 بار
  • آخرین بروزرسانی: 10 مارس '12, 23:49

این سوال را دنبال کنیدتوسط ایمیل: ایمیل شما (باید معتبر باشد, هرگز به دیگران نمایش داده نمیشود):

هنگامی که شما به سیستم وارد شوید،قادر خواهید بود برای بروز رسانی ها مشترک شوید.


توسط RSS:

پاسخها

پاسخها و نظرها