سازنده ها (Constructors)

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

   1: #include <iostream>
   2: #include <string>
   3: using namespace std;
   4: 
   5: class Person
   6: {
   7: public:
   8:     string name;
   9:     int age;
  10:     double height;
  11: 
  12:     //Explicitly declare a default constructor            
  13:     Person()
  14:     {
  15:     }
  16: 
  17:     //Constructor that has 3 parameters                   
  18:     Person(string n, int a, double h)
  19:     {
  20:         name = n;
  21:         age = a;
  22:         height = h;
  23:     }
  24: 
  25:     void ShowInformation()
  26:     {
  27:         cout << "Name: " << name << endl;
  28:         cout << "Age: " << age << " years old" << endl;
  29:         cout << "Height: " << height << "cm" << endl;
  30:     }
  31: };
  32: 
  33: int main()
  34: {
  35:     Person firstPerson;
  36:     Person secondPerson("Mike", 23, 158);
  37: 
  38:     firstPerson.name = "Jack";
  39:     firstPerson.age = 21;
  40:     firstPerson.height = 160;
  41:     firstPerson.ShowInformation();
  42: 
  43:     cout << endl; //Seperator                  
  44: 
  45:     secondPerson.ShowInformation();
  46: }
Name: Jack
Age: 21 years old
Height: 160cm

Name: Mike
Age: 23 years old
Height: 158cm

همانطور که مشاهده می کنید در مثال بالا دو سازنده را به کلاس Person اضافه کرده ایم. یکی از آنها سازنده پیشفرض (خطوط 12-10) و دیگری سازنده ای است که سه آرگومان قبول می کند (خطوط 20- 15).
به این نکته توجه کنید که سازنده درست شبیه به یک متد است با این تفاوت که

  • نه مقدار برگشتی دارد و نه از نوع void است.
  • نام سازنده باید دقیقا شبیه نام کلاس باشد.

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

Person firstPerson;
Person secondPerson("Mike", 23, 158);

در اولین نمونه ایجاد شده از کلاس Person از سازنده پیشفرض استفاده کرده ایم چون پارامتری برای دریافت آرگومان ندارد. در دومین نمونه ایجاد شده، از سازنده ای استفاده می کنیم که دارای سه پارامتر است. کد زیر تاثیر استفاده از دو سازنده مختلف را نشان می دهد :

firstPerson.name = "Jack";
firstPerson.age = 21;
firstPerson.height = 160;
firstPerson.ShowInformation();

cout << endl; //Seperator

secondPerson.ShowInformation();

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

اختصاص مقادیر پیشفرض به سازنده پیشفرض

در مثالهای قبلی یک سازنده پیشفرض با بدنه خالی نشان داده شد. شما می توانید به بدنه این سازنده پیشفرض کدهایی اضافه کنید. همچنین می توانید مقادیر پیشفرضی به فیلدهای آن اختصاص دهید.

Person()
{
   name = "No Name";
   age = 0;
   height = 0;
}

همانطور که در مثال بالا می بینید سازنده پیشفرض ما چیزی برای اجرا دارد. اگر نمونه ای ایجاد کنیم که از این سازنده پیشفرض استفاده کند ، نمونه ایجاد شده مقادیر پیشفرض سازنده پیشفرض را نشان می دهد.

Person person1;

person1.ShowInformation();
Name: No Name
Age: 0 years old
Height: 0cm

استفاده از کلمه کلیدی this

راهی دیگر برای ایجاد مقادیر پیشفرض استفاده از کلمه کلیدی this است. فرض کنید نام پارامترهای متد کلاس شما یا سازنده، شبیه نام یکی از فیلدها باشد.

Person(string name, int age, double height)
{
   name = name;
   age = age;
   height = height;
}

این نوع کدنویسی ابهام بر انگیز است و کامپایلر نمی تواند متغیر را تشخیص داده و مقداری به آن اختصاص دهد. اینجاست که از کلمه کلیدی this استفاده می کنیم.

Person(string name, int age, double height)
{
    this->name = name;
    this->age = age;
    this->height = height;
}  

قبل از هر فیلدی کلمه کلیدی this را می نویسیم و نشان می دهیم که این همان چیزی است که می خواهیم به آن مقداری اختصاص دهیم. کلمه کلیدی this ارجاع یک شی به خودش را نشان می دهد.