تبدیل ضمنی در دادههای تعریف شده توسط کاربر وقتی انجام میشه که یه سازندهی متناسب براش پیدا بشه. مثلاً فرض کنیم کلاس زیر و داریم
class C1
{
private:
int _num;
public:
C1(){ this->_num = 0; };
~C1(){ ... };
};
حالا فرض کنیم بخوایم کد زیر در برنامه کار کنه
int main()
{
C1 obj;
obj = 4;
}
در این صورت اگه بدون تبدیل کد قابل اجرا باشه یعنی عملگر انتساب از int
به C1
یعنی عملگر زیر سربارگذاری شده
const C1& operator=(int x)
{
this->_num = x;
return *this;
}
در کد obj = 3;
هیچ تبدیلی وجود نداره بلکه یک عملگر سربارگذاری شده فراخوانی شده.
اما اگه این عملگر و پیادهسازی کرده باشیم کد زیر هم کار میکنه
C1 obj;
obj = 1.4;
در حقیقت ما از تبدیل ضمنی کامپایلر برای هدف خودمون استفاده کردیم. ابتدا 1.4 تبدیل به عدد صحیح 1 میشه و بعد از انتساب پیادهسازی شده استفاده میشه. بنابراین در این حالت یک تبدیل ضمنی غیرمستقیم مورد استفاده قرار گرفته.
در مورد عملگرهای دیگه هم همین قاعده وجود داره. مثلاً برای عملگر +
اگه بخوایم کد زیر اجرا بشه
C1 obj1, obj2;
obj1 = obj2 + 10;
در صورتی که بخوایم این کد کار کنه میتونیم عملگر زیر و سربارگذاری کنیم
const C1& operator+(int x)
{
C1 tmp;
tmp._num += x;
return tmp;
}
در این جا باز هم کد obj1 = obj2 + 10.5
از یک تبدیل ضمنی غیرمستقیم استفاده میکنه.
اما میشه این کارها رو با یه سازنده انجام داد. سازندهی زیر رو در نظر بگیریم
C1(int x){ this->_num = x; };
حالا هر کجا که یه int
در یه عبارت محاسباتی با C1
به کار رفته باشه کامپایلر int
رو به C1
تبدیل میکنه و کد رو کامپایل میکنه.
در صورتی که یه float
در عمل محاسباتی با C1
به کار رفته باشه& کامپایلر ابتدا float
رو به int
و سپس int
رو به C1
تبدیل میکنه.
در این صورت obj1 = 10
و obj1 = obj2 + 5.5
در حقیقت از تبدیلهای ضمنیای استفاده میکنن که برنامهنویس پیاده کرده.
هیچ پژوهش انسانی نمیتواند ادعای علمی بودن داشته باشد، مگر اینکه از برهان ریاضی برخوردار باشد (لئوناردو داوینچی)