سلام!

این جلسه باز هم قرار است به یک مبحث بسیار کاربردی و پایه ای به نام تابع سازنده یا constructor بپردازیم.

تابع سازنده تابعی است که وقتی که یک object از class بسازیم، صدا زده می شود. این تابع چند خصوصیت دارد:

۱. خروجی ندارد.

۲. دقیقا هم اسم class است.

۳. فقط یک بار قابل استفاده است.

برای این که بهتر منظورم را متوجه شوید، به مثال زیر دقت کنید.


#include <iostream>

#include <cmath>

using namespace std;

class Car{
    private:
        int width, height, maxSpeed, maxAcceleration, currentSpeed, currentAcceleration;
    public:
        
        void setWidth(int);
        void setHeight(int);
        void setMaxSpeed(int);
        void setMaxAcceleration(int);
        void setCurrentSpeed(int);
        void setCurrentAcceleration(int);

        int getWidth();
        int getHeight();
        int getMaxSpeed();
        int getMaxAcceleration();
        int getCurrentSpeed();
        int getCurrentAcceleration();
};

void Car::setWidth(int newWidth){
    width = newWidth;
}

void Car::setHeight(int newHeight){
    height = newHeight;
}

void Car::setMaxSpeed(int newMaxSpeed){
    maxSpeed = newMaxSpeed;
}

void Car::setMaxAcceleration(int newMaxAcceleration){
    maxAcceleration = newMaxAcceleration;
}

void Car::setCurrentSpeed(int newCurrentSpeed){
    if ( abs(newCurrentSpeed) <= maxSpeed) //abs: ghadre motlagh
        currentSpeed = newCurrentSpeed;
    else cout << "ERROR! newCurrentSpeed is " << newCurrentSpeed << " while maxSpeed is " << maxSpeed << endl;
}

void Car::setCurrentAcceleration(int newCurrentAcceleration){
    if ( abs(newCurrentAcceleration) <= maxAcceleration)
        currentAcceleration = newCurrentAcceleration;
    else cout << "ERROR! newCurrentAcceleration is " << newCurrentAcceleration << " while maxAcceleration is " << maxAcceleration << endl;
}

int Car::getWidth(){
    return width;
}

int Car::getHeight(){
    return height;
}

int Car::getMaxSpeed(){
    return maxSpeed;
}

int Car::getMaxAcceleration(){
    return maxAcceleration;
}

int Car::getCurrentSpeed(){
    return currentSpeed;
}

int Car::getCurrentAcceleration(){
    return currentAcceleration;
}

int main(){
    Car car;
    car.setWidth(100);
    car.setHeight(100);
    car.setMaxSpeed(100);
    car.setMaxAcceleration(30);
    car.setCurrentSpeed(-120);
    car.setCurrentSpeed(50);
    car.setCurrentAcceleration(50);
    car.setCurrentAcceleration(20);
}

این مثال همان طوری نوشته شده که شما هم احتمالا استفاده می کنید اما برای این که مقداردهی اولیه ی متغیرها راحت تر انجام شود، می توانید مانند مثال زیر عمل کنید؛

#include <iostream>
#include <cmath>

using namespace std;

class Car{
    private:
        int width, height, maxSpeed, maxAcceleration, currentSpeed, currentAcceleration;
    public:
        
        Car(int, int, int, int, int, int);

        void setWidth(int);
        void setHeight(int);
        void setMaxSpeed(int);
        void setMaxAcceleration(int);
        void setCurrentSpeed(int);
        void setCurrentAcceleration(int);

        int getWidth();
        int getHeight();
        int getMaxSpeed();
        int getMaxAcceleration();
        int getCurrentSpeed();
        int getCurrentAcceleration();
};

Car::Car(int width, int height, int maxSpeed, int maxAcceleration, int currentSpeed, int currentAcceleration){
    this->setWidth(width);
    this->setHeight(height);
    this->setMaxSpeed(maxSpeed);
    this->setMaxAcceleration(maxAcceleration);
    this->setCurrentSpeed(currentSpeed);
    this->setCurrentAcceleration(currentAcceleration);
}

void Car::setWidth(int newWidth){
    width = newWidth;
}

void Car::setHeight(int newHeight){
    height = newHeight;
}

void Car::setMaxSpeed(int newMaxSpeed){
    maxSpeed = newMaxSpeed;
}

void Car::setMaxAcceleration(int newMaxAcceleration){
    maxAcceleration = newMaxAcceleration;
}

void Car::setCurrentSpeed(int newCurrentSpeed){
    if ( abs(newCurrentSpeed) <= maxSpeed) //abs: ghadre motlagh
        currentSpeed = newCurrentSpeed;
    else cout << "ERROR! newCurrentSpeed is " << newCurrentSpeed << " while maxSpeed is " << maxSpeed << endl;
}

void Car::setCurrentAcceleration(int newCurrentAcceleration){
    if ( abs(newCurrentAcceleration) <= maxAcceleration)
        currentAcceleration = newCurrentAcceleration;
    else cout << "ERROR! newCurrentAcceleration is " << newCurrentAcceleration << " while maxAcceleration is " << maxAcceleration << endl;
}

int Car::getWidth(){
    return width;
}

int Car::getHeight(){
    return height;
}

int Car::getMaxSpeed(){
    return maxSpeed;
}

int Car::getMaxAcceleration(){
    return maxAcceleration;
}

int Car::getCurrentSpeed(){
    return currentSpeed;
}

int Car::getCurrentAcceleration(){
    return currentAcceleration;
}

int main(){
    Car car(100, 100, 100, 30, 120, 20);
/*    car.setWidth(100);
    car.setHeight(100);
    car.setMaxSpeed(100);
    car.setMaxAcceleration(30);
    car.setCurrentSpeed(-120);
    car.setCurrentSpeed(50);
    car.setCurrentAcceleration(50);
    car.setCurrentAcceleration(20);*/
}

همان طور که احتمالا می دانید تابع ها با ۳ چیز از هم تمیز داده می شوند: اسم، ورودی ها و const بودن که راجع به توابع const صحبت خواهیم کرد. اگر ۲ تابع در یکی از این ۳ مورد با هم تفاوت داشته باشند، می توانند همزمان تعریف شوند. بنابراین شما می توانید چند تابع سازنده درست کنید با ورودی های متفاوت و یا تفاوت در const بودن.

حالا می خواهیم شما را با نوعی از توابع آشنا کنیم که خیلی به درد توابع سازنده می خورند. تابع زیر را در نظر بگیرید:

int function(int a);

حالا اگر بخواهید از این تابع استفاده کنید، به صورت زیر عمل می کنید:

function(53);

حالا به تابع زیر دقت کنید:

int function(int a = 0);

حالا می توانید به دو صورت از این تابع استفاده کنید، هم

function(63);

و هم

function();

به این نوع ورودی ورودی های پیش فرض می گویند. مثلا در مثال بالا اگر از صورت پایینی استفاده کنیم، ورودی تابع ۰ خواهد بود (همان مقداری که به a در قسمت ورودی های تابع دادیم). برای آشنایی بیشتر می توانید به مثال زیر دقت کنید.

#include <iostream>

using namespace std;

int function(int input = 0){
    return input * 5;
}

int main(){
    cout << "Input 53: " << function(53) << "\nNo input: " << function() << endl;
    return 0;
}

حال از همین صورت تعریف تابع می توانید برای توابع سازنده نیز استفاده کنید. مثلا مثل مثال زیر؛

#include <iostream>

using namespace std;

class Car{
    private:
        int speed;
    public:
        Car(int = 0);

        int getSpeed();
        void setSpeed(int);
};

Car::Car(int speed){
    this->setSpeed(speed);
}

int Car::getSpeed(){
    return this->speed;
}

void Car::setSpeed(int speed){
    this->speed = speed;
}

int main(){
    Car firstCar;
    Car secondCar(50);
    cout << "firstCar's Speed is " << firstCar.getSpeed() << " And The secondCar's Speed is " << secondCar.getSpeed() << endl;
    return 0;
}

برای تمرین این مبحث می توانید کدهایی که برای این تمرین نوشته اید، ارتقا دهید. قرار بود که تا اینجا آن ها را با this بنویسید.

موفق باشید!