رفتن به مطلب
مرجع رسمی سی‌پلاس‌پلاس ایران

سوال

سلام وقت بخیر و شادی 

مطالعه ای در باره مورد های delete keyword و explicit داشتم اما متاسفانه نتوانستم کاربردهاشون و متوجه بشم

و میخواستم بدونم ایا تعریفی که از این دو مورد متوجه شدم درست است یا که خیر

delete keyword اقدام به حذف کانستراکتور های پیش فرض می کند . 

explicit اقدام به افزایش میکنه ( منظورم این که اول کانستراکتوری که ما بهش explicit اختصاص دادیم اتفاق بی افته بعدا کانستراکتور های بعدی )

متشکرم

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

1 پاسخ به این سوال تا کنون داده شده است

پست های پیشنهاد شده

  • 2

سلام 

خب اول برات delete رو میگم که ساده تره ?. شما یه توی برنامه نویسی شئ گرا که کار با کلاس ها (class) پیش میاد. همانطوری که میدونید توابعی به صورت پیشفرض کامپایلر داخل کلاس تعریف میکنه. که یکی از این توابع اسمش سازنده (constructor) هست که وظیفه مقدار دهی کلاس را داره. 

این مثال رو در نظربگیرید :

#include <iostream>

class JustForTest{
  private :
    int ClassVariable;
  public  :
    JustForTest(const int& input) :
      ClassVariable(input){

    }

    int ReturnClassVariable(){
      return this->ClassVariable;
    }
};


int main(){
  JustForTest Object(10);
  std::cout << Object.ReturnClassVariable () << std::endl;
  return 0;
}

خب کاری که داخل این کلاس انجام شده اینکه یه کلاس به اسم JustForTeste تعریف شده که دارای یه متغیر و دو تابع عضو هست. که یکی از توابع ، تابع سازنده کلاس هست. این برنامه در اجرا هیچ مشکلی نداره و دقیقا همان چیزی که ما انتظار داریم را چاپ میکنه ، که مقدار ده هست. 

حالا مشکل وقتی پیش میاد که برنامه نویسی بیاد و از کلاس شما استفاده کنه و سهواً مقداری از نوع char به سازنده کلاس ارسال کنه :

int main(){
  JustForTest Object('3');
  std::cout << Object.ReturnClassVariable () << std::endl;
  return 0;
}

بر خلاف انتظارمان این کد هم کامپایل میشه ، چرا که خود char نوعی از int هست. و مسلما خروجی نامناسبی هم داره. 

برای اینکه این مشکل رفع بشه اغلب برنامه نویس ها از این روش استفاده میکنن :

class JustForTest{
  private :
    int ClassVariable;
    JustForTest(const char& input){
      
    }
  public  :
    JustForTest(const int& input) :
      ClassVariable(input){

    }

    int ReturnClassVariable(){
      return this->ClassVariable;
    }
};

 به این صورت که سازنده ای با ورودی char را با نوع دسترسی private تعریف میکنن که باعث میشه برنامه نویس های دیگر نتوانن مقدار از نوع char به تابع شما ارسال کنن. 

اما ! واضحه که این روش زیاد جالب نیست و باعث ناخوانی و زشتی کد هم میشه. لذا بهتره که با استفاده از قابلیتی که سی پلاس پلاس فراهم کرده استفاده کنیم و این سازنده را از کلاس حذف کنیم. که این کار با استفاده از کلمه کلیدی delete صورت میگیره :

class JustForTest{
  private :
    int ClassVariable;
  public  :
    JustForTest(const int& input) :
      ClassVariable(input){

    }
    JustForTest(const char& input) = delete;

    int ReturnClassVariable(){
      return this->ClassVariable;
    }
};

به همین سادگی و بدون خون ریزی :classic_biggrin:

 

و اما کلمه کلیدی explicit :

تقریبا ماننده همون مثالی هست که برای کلمه کلیدی delete در قسمت بالا زدم. همانطوری که دیدید با اینکه ما مقدار char به تابع سازنده کلاس ارسال کردیم بدون مشکل برنامه کامپایل و اجرا شد. اما اتفاقی که پشت صحنه افتاده این بوده که : کامپایلر خودش مقدار char را به int تبدیل (cast) کرده. 

برای اینکه از این تبدیل جلوگیری کنیم. از کلمه کلیدی explicit قبل از تابع سازنده استفاده میکنیم :

#include <iostream>

class JustForTest{
  private :
    int ClassVariable;
  public  :
    explicit JustForTest(const int& input) :
      ClassVariable(input){

    }

    int ReturnClassVariable(){
      return this->ClassVariable;
    }
};

int main(){
  JustForTest Object = '3';
  std::cout << Object.ReturnClassVariable () << std::endl;
  return 0;
}

برنامه ی بالا کامپایل نخواهد شد. چرا که هیچ تابع سازنده ای با پارامتر char پیدا نشده !

اما ممکنه که سوال بپرسید : پس فرق explicit با delete در چی هست ؟

جواب سوال : اگه کمی به کد دقت کنید متوجه میشید که ما با استفاده از Copy initialization (یعنی استفاده از = برای مقدار دهی) سازنده کلاس را مقدار دادیم. ولی درصورتی که از direct یا uniform initialization استفاده کنیم کد ما همچنان کامپایل میشود..

مثال  :

int main(){
  JustForTest Object('3');
  std::cout << Object.ReturnClassVariable () << std::endl;
  return 0;
}

خب برای اینکه به طور کلی ما تابع سازنده ای با پارامتر char را محدود کنیم باید از کلمه کلیدی delete‌ استفاده کنیم.

 

 

خلاصه :

کلمه کلیدی explicit برای محدود کردن تبدیل نوع در پارامتر کلاس هست. اما این در زمانی اتفاق می افتد که ما از copy initialization برای مقداردهی سازنده کلاس استفاده کنیم. و در صورت استفاده از direct یا uniform initialization دیگه این عمل امکان پذیر نیست.

و برای اینکه یک تابع را به کلی از کلاس محدود کنیم از کلمه کلیدی delete استفاده میکنیم که باعث میشود هیچ شئ توانایی فراخوانی آن تابع را نداشته باشد. 

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

به گفتگو ملحق شوید

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

مهمان
پاسخ به این سوال ...

×   شما در حال چسباندن محتوایی با قالب بندی هستید.   حذف قالب بندی

  تنها استفاده از ۷۵ اموجی مجاز می باشد.

×   لینک شما به صورت اتوماتیک جای گذاری شد.   نمایش به عنوان یک لینک به جای

×   محتوای قبلی شما بازگردانی شد.   پاک کردن محتوای ویرایشگر

×   شما مستقیما نمی توانید تصویر خود را قرار دهید. یا آن را اینجا بارگذاری کنید یا از یک URL قرار دهید.


  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×
×
  • جدید...