نمایش نتایج 1 تا 3 از 3

نام تاپیک: نا مفهوم بودن Copy Constructor

  1. #1

    Unhappy نا مفهوم بودن Copy Constructor

    با سلام خدمت دوستان من مفهوم سازنده ها یا همون Constructor ها رو بلدم اما درک و مفهوم سازنده کپی یا همون Copy Constructor برام نا مفهومه و دقیقا متوجه نمیشم چه کاری انجام میده ممنون میشم اگه کسی از دوستان بتونه کار و مفهوم Copy Constructor رو برای من باز کنه و با یک مثال سینتکس رو به من نشون بده که متوجه بشم و سوال دیگه اینکه ایا Copy Constructor کاربردی هم داره هنوز ؟ اگر داره در چه جاهایی میشه ازش استفاده کرد

  2. #2
    کاربر دائمی آواتار vahid-p
    تاریخ عضویت
    آذر 1391
    محل زندگی
    تهران
    پست
    1,140

    نقل قول: نا مفهوم بودن Copy Constructor

    تقریبا همون کار متد clone() رو انجام میده (گرچه در این لینک توضیح داده که چرا از clone استفاده نکنید و حتی در برخی داکیومنت های لایبرری اندروید هم در خصوص این متد چنین توضیحاتی داده بود.


    اما به جای clone میتونیم از copy constructor استفاده کنیم یا متدی که چنین کاری رو انجام بده.


    خب برای چی اصلا به چنین چیزی نیاز داریم. فرض کنید ما کلاسی داریم به این شکل:
    public class Example {
    private int x;
    private int y;
    private String z;

    public Example(){
    this.x=10;
    this.y=10;
    this.z="Hi";
    }


    public void setX(int x) {
    this.x = x;
    }


    public void setY(int y) {
    this.y = y;
    }


    public void setZ(String z) {
    this.z = z;
    }
    }



    فرض کنید بخوایم یه آبجکت ازش بسازیم و پارامترهاش رو تغییر بدیم.
        public static void main(String[] args) {
    Example o1=new Example();
    o1.setX(10);
    o1.setY(20);
    o1.setZ("Ali");
    System.out.println(o1.toString());
    }
    }

    خروجی:
    X=10, Y=20, Z=Ali


    اما فرض کنید میخوایم آبجکتی رو بسازیم که دقیقا همون مقادیر این آبجکت رو داشته باشه و فقط مقدار z رو تغییر بدیم و به اسم hasan تغییر بدیم. خب. مطمئنا میگید:

    public static void main(String[] args) {
    Example o1=new Example();
    o1.setX(10);
    o1.setY(20);
    o1.setZ("Ali");
    Example o2=o1;
    o2.setZ("Hasan");
    System.out.println(o1.toString());
    System.out.println(o2.toString());
    }

    اما خروجیمون میشه:
    X=10, Y=20, Z=Hasan
    X=10, Y=20, Z=Hasan


    در صورتی که انتظار داشتیم اولی Ali باقی بمونه.
    این دقیقا به خاطر اینه که Assign کردن یک آبجکت به آبجکت (o2=o1) دیگه، فقط یک اشاره گر به همون آبجکت اولی (o1) هست و در نتیجه هر تغییری بر روی دومی (o2) همون آبجکت اولی تغییر خواهد کرد و در اصل فقط همون یک آبجکت وجود داره.
    حتی اگر در مثال بالا به این صورت عمل کنید هم تفاوتی نداره:
    Example o2=new Example();
    o2=o1;

    و نتیجه همون خواهد بود چرا که آبجکت جدید بلااستفاده میشه. برای اینکار شما باید تمام فیلدهای primitive یک آبجکت رو کپی کنید (مانند int, double, float ,... چون متغیرهایی هستند که مقدارشون ذخیره میشه و نه فقط یک رفرنس به محل شی). اگر چه String یک آبجکت است و primitive نیست، اما چون immutable است با اینکه نمیشه کپی کرد و اما همون Assign کردن جواب میده (بخونید immutable چیه تا دلیلش رو متوجه بشید، خلاصش اینه که هر تغییری در مقادیر این آبجکت، یک آبجکت جدیدی رو میسازه و قبلی تغییر نمیکنه)

    خب پس برای اینکار یک کانستراکتور مینویسیم که از این به بعد بتونیم راحت یک آبجکت شبیه آبجکتی که داشتیم بسازیم. برای اینکار بهترین محل همون کلاس هست، چرا که به فیلدهای private اش دسترسی داریم و نیازی به متدهای get نیست ( برای کلاس های خارجی فقط میتونیم از متد get به فیلد های private دسترسی داشته باشیم که بدیهیه)

    خب پس به کلاس اولیمون این رو اضافه می کنیم:
        public Example(Example ex){
    this.x=ex.x;
    this.y=ex.y;
    this.z=ex.z;
    }


    این نکته جالبه با اینکه ما به فیلدهای یک آبجکت ex از نوع private دسترسی داریم ولی کامپایلر هیچ ارروری نمیده، چون تشخیص میده که این کلاس و کلاس آبجکتی که بهش دسترسی داریم یکیه.

    اما کد:
        public static void main(String[] args) {
    Example o1=new Example();
    o1.setX(10);
    o1.setY(20);
    o1.setZ("Ali");
    Example o2=new Example(o1);
    o2.setZ("Hasan");
    System.out.println(o1.toString());
    System.out.println(o2.toString());
    }

    خروجی:
    X=10, Y=20, Z=Ali
    X=10, Y=20, Z=Hasan

    دقیقا همونی که میخواستیم. خب واضحه!

    اینم یه نمونه دیگه:
        public Example(int x, int y, String z){
    this.x=x;
    this.y=y;
    this.z=z;
    }

    public Example(Example ex){
    this(ex.x,ex.y,ex.z);
    }


    البته باید توجه داشته باشی که برای تمام فیلدهای primitive و فیلد آبجکت ها immutable اینکار رو مستقیما میتونید انجام بدید (و باید برای تمام فیلدها باشه)
    اما فرض کنید یکی از فیلدها خودش یک آبجکت بود. در اینحالت شما در کانستراکتور کپی خودتون باید کپی از اون آبجکت هم بسازید. البته توجه کنید در این حالت نمیتونید از خود این کلاس استفاده کنید چرا که باید کلاس ها به جایی برسن که دوباره نخواد کپی از یک آبجکت بسازه. یعنی آخرش باید به فیلدهای primitive برسن. فکر کنم یکم گنگ شد. بهتره یه مثال بزنم.
    در چنین حالتی ما نمی تونیم از آبجکتی از کلاس فعلیمون داشته باشیم و از اون کپی بسازیم:
    public class Example {
    private int x;
    private int y;
    private String z;
    private Example o;

    public Example(int x, int y, String z){
    this.x=x;
    this.y=y;
    this.z=z;
    o=new Example(30,40,"Saeed");
    }

    public Example(Example ex){
    this(ex.x,ex.y,ex.z);
    this.o=new Example(ex.o);
    }


    public void setX(int x) {
    this.x = x;
    }


    public void setY(int y) {
    this.y = y;
    }


    public void setZ(String z) {
    this.z = z;
    }


    @Override
    public String toString() {
    return "X="+x+", Y="+y+", Z="+z;
    }
    }






    دلیلشم اینه تو یک loop تا بی نهایت آبجکت میسازه و در نهایت Stackoverflow!
    پس یه سری نکات داره که باید رعایت بشه.
    آخرین ویرایش به وسیله vahid-p : پنج شنبه 09 اردیبهشت 1395 در 18:38 عصر دلیل: اضافه کردن لینک

  3. #3

    نقل قول: نا مفهوم بودن Copy Constructor

    ... (بخونید immutable چیه تا دلیلش رو متوجه بشید، خلاصش اینه که هر تغییری در  مقادیر این آبجکت، یک آبجکت جدیدی رو میسازه و قبلی تغییر نمیکنه)

    چون اسم از طراحی «تغییرناپذیر» (Immutable) به میون اومد مناسب دیدم که توضیحی در این مورد بدم.. درسته که با روش‌های مختلفی می‌تونیم یک شیٔ رو همانندسازی (Clone) کنیم، اما در اکثر موارد راه هوشمندانه‌تر اینه که سعی کنیم طراحیمون رو Immutable نگهداریم؛ اینجوری با بسیاری از محدودیت‌ها و پیچیدگی‌ها روبرو نیستیم و در مقابل تضمین می‌کنیم مشکلی مثل چیزی که در مورد Assignها مثال زدی پیش نمی‌آد.
    • البته این معنیش این نیست که طراحی Immutable همیشه خوبه!


    public class Example {
    private final int x;
    private final int y;
    private final String z;

    public Example(int x, int y, String z){
    this.x = x;
    this.y = y;
    this.z = z;
    }

    public Example withX(int x) {
    return new Example(x, this.y, this.z);
    }

    public Example withY(int y) {
    return new Example(this.x, y, this.z);
    }

    public Example withZ(String z) {
    return new Example(this.x, this.y, z);
    }

    @Override
    public String toString() {
    return "X=" + x + ", Y=" + y + ", Z=" + z;
    }
    }

    اینجوری علاوه بر ساده‌شدن کار خودمون، احتمال اشتباه استفاده کردن از کلاسمون رو به حداقل می‌رسونیم:


    public static void main(String[] args) {
    Example o1 = new Example(2, 2, "Steve");
    Example o2 = o1.withY(3).withZ("Jobs");

    System.out.println(o1);
    System.out.println(o2);
    }

    آخرین ویرایش به وسیله محمد فدوی : پنج شنبه 09 اردیبهشت 1395 در 23:31 عصر
    اگر به بهداشت و سلامت حیوانات علاقه دارید، از vetMD.ir دیدن کنید.
    وبلاگ شخصی من: fadavi.net

    اینجا کمتر سر می‌زنم. (تلگرام من)

تاپیک های مشابه

  1. Copy Constructor
    نوشته شده توسط JalaliMehr در بخش برنامه نویسی با MFC و ++Visual C
    پاسخ: 3
    آخرین پست: شنبه 09 مرداد 1389, 00:04 صبح
  2. نا مفهوم بودن خطا
    نوشته شده توسط majidta در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 1
    آخرین پست: دوشنبه 21 اردیبهشت 1388, 01:32 صبح
  3. DELETE نا مفهوم
    نوشته شده توسط saber4166 در بخش C#‎‎
    پاسخ: 6
    آخرین پست: چهارشنبه 30 مرداد 1387, 00:34 صبح
  4. کم و نا مناسب بودن شکلک ها
    نوشته شده توسط aakh1361 در بخش گفتگو با مسئولین سایت، درخواست و پیشنهاد
    پاسخ: 9
    آخرین پست: پنج شنبه 26 آبان 1384, 00:24 صبح
  5. یک Error نا مفهوم و بی موقع
    نوشته شده توسط Chabok در بخش VB.NET
    پاسخ: 0
    آخرین پست: یک شنبه 25 اردیبهشت 1384, 21:08 عصر

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •