PDA

View Full Version : تفاوت تبدیل نوع reinterpret_cast و static_cast ؟



one hacker alone
چهارشنبه 17 خرداد 1391, 01:00 صبح
با یاد خدا
همون طور که میدونید ما دو نوع تبدیل نوع داریم که یکیش همون روش سنتی بود مثل (int) یکی هم روش جدید که ما از reinterpret_cast یا static_cast استفاده میکنیم به این شکل reinterpret_cast<int> حالا میخواستم بدونم تفاوتشون در چیه و اینکه ایا هرکدوم باید در جای بخصوصی استفاده بشه؟

mehdi.mousavi
سه شنبه 30 خرداد 1391, 13:19 عصر
با یاد خدا همون طور که میدونید ما دو نوع تبدیل نوع داریم که یکیش همون روش سنتی بود مثل (int) یکی هم روش جدید که ما از reinterpret_cast یا static_cast استفاده میکنیم به این شکل reinterpret_cast<int> حالا میخواستم بدونم تفاوتشون در چیه و اینکه ایا هرکدوم باید در جای بخصوصی استفاده بشه؟

سلام.
قبل از توضیح اون دو مدل cast اجازه بدید به این مساله اشاره کنم که 5 نوع Casting Operator (http://msdn.microsoft.com/en-us/library/5f6c9f8h) وجود داره (و نه دو نوع) و اینجا فقط در مورد این دو مدلی که پرسیدید توضیح میدم. static_cast، برای تبدیل pointer ها یا حتی اعداد با Data Type های مختلف به یکدیگر استفاده میشه. فرض کنید دو کلاس داشته باشیم:


class CBase
{
};

class CParent: public CBase
{
};


با استفاده از static_cast می تونیم از pointer ای به کلاس Parent رو به Pointer ای به کلاس Base (و برعکس) تبدیل کنیم:

CBase *pBase = new CBase();
CParent *pParent = static_cast<CParent *>(pBase);
CBase *pOriginal = static_cast<CBase *>(pParent);

البته در این تبدیل ها، Type شیء نهایی چک نمیشه و این وظیفه برنامه نویس هستش که بدونه داره چی رو به چی Cast می کنه (اگر مایلید Object Type هم هنگام تبدیل بررسی بشه، باید از dynamic_cast استفاده کنید). اما static_cast برای تبدیل اعداد نیز میتونه مورد استفاده قرار بگیره:

float f = 12.34567;
int i = static_cast<int>(f); // i == 12

(حتما می پرسید خوب حالا فرق این با Cast کردن معمولی چیه؟ خوب، صبر داشته باشید به اون هم خواهیم رسید).

اما در reinterpret_cast، دست برنامه نویس برای هر نوع تبدیلی بازه. یعنی شما می تونید Pointer به کلاس A رو، به Pointer به کلاس X که A و X هیچ ارتباطی با هم ندارن، cast کنید. عمل cast بدرستی انجام خواهد شد، اما de-reference کردن pointer جدید کاری unsafe هستش چرا که داره به کلاس ناسازگاری اشاره می کنه. عموما اینکار تنها وقتی به درد میخوره که شما قبل از de-reference کردن pointer جدید، اونو مجددا به pointer ای از کلاس سازگار cast کنید.

اما وقتی شما از C-Style Cast ها استفاده می کنید، چه اتفاقی می افته؟ در حقیقت سیستم به ترتیب شروع می کنه ببینه کدامیک از cast های زیر شدنیه و اونو براش شما انجام میده:


const_cast
static_cast
static_cast و سپس const_cast
reinterpret_cast
reinterpret_cast و سپس const_cast

موفق باشید.

پاورقی: برای توضیحات بیشتر، می تونید پاسخ اول در این تاپیک (http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used) رو مطالعه کنید.