سلام!

در این جلسه قرار است در رابطه با عمل گر ها نکاتی را یاد بگیرید و چگونگی تغییر آن ها را بیاموزید.

فرض کنید یک class به نام Point نوشته اید که شامل دو مؤلّفه (x و y) است. این کار را جلسه ی پیش انجام دادید. اگر انجام ندادید می توانید از کد زیر استفاده کنید.

#include <iostream>
#include <cstdio>

using namespace std;

class Point{
    
    friend void set(Point*, int = 0, int = 0);

    private:

        int _x, _y;
        
        void setX(int);
        void setY(int);
    
    public:

        Point(int = 0, int = 0);

        int x() const;
        int y() const;

};

Point::Point(int x, int y){
    set(this, x, y);
}

void Point::setX(int x){
    this->_x = x;
}

void Point::setY(int y){
    this->_y = y;
}

int Point::x() const{
    return this->_x;
}

int Point::y() const{
    return this->_y;
}

void set(Point *point, int x, int y){
    point->setX(x);
    point->setY(y);
}

int main(){
    int x, y;
    scanf("%d %d", &x, &y);
    Point point(x, y);
    printf("X: %d\nY: %d\n", point.x(), point.y());
    return 0;
}

حالا می خواهید مفهومی را پیاده سازی کنید به نام جمع دو نقطه که در آن مؤلّفه های x را با هم و مؤلّفه های y را با هم جمع می کنید. به طور معمول احتمالا شما تابعی پیاده سازی می کنید و در آن جمع دو نقطه را تعریف می کنید مثل کد زیر؛

#include <iostream>
#include <cstdio>

using namespace std;

class Point{
    
    friend void set(Point*, int = 0, int = 0);

    private:

        int _x, _y;
        
        void setX(int);
        void setY(int);
    
    public:

        Point(int = 0, int = 0);

        int x() const;
        int y() const;

        void print();

};

Point::Point(int x, int y){
    set(this, x, y);
}

void Point::setX(int x){
    this->_x = x;
}

void Point::setY(int y){
    this->_y = y;
}

int Point::x() const{
    return this->_x;
}

int Point::y() const{
    return this->_y;
}

void Point::print(){
    printf("(%d, %d)", this->x(), this->y());
}

void set(Point *point, int x, int y){
    point->setX(x);
    point->setY(y);
}

Point sum(Point p1, Point p2){
    return Point(p1.x() + p2.x(), p1.y() + p2.y());
}

int main(){
    Point *p1 = new Point(54, 12);
    Point *p2 = new Point(4, 23);
    Point pointsSum = sum(*p1, *p2);
    pointsSum.print();
}

حالا می خواهیم کاری کنیم که کد خواناتر شود. برای این کار می توانیم برای نقطه علامت جمع (+) را تعریف کرده و سپس در برنامه به جای این که بنویسیم

Point pointsSum = sum(p1, p2);

تنها بنویسیم

Point pointsSum = p1 + p2;

همان طور که واضح است، compiler نمی داند که چه طور دو نقطه را با هم جمع کند و برای همین error می دهد. بنابراین باید علامت جمع را برای نقطه تعریف کنید. برای این کار باید بنویسید

Point operator+(Point, Point);

خیلی شبیه تعریف یک تابع است، سمت چپ باید خروجی را بنویسید، سپس اسم تابع و سپس ورودی ها. این جا هم همین طور است؛ سمت چپ خروجی، سپس اسم (که عبارت است از کلمه ی operator و سپس خود operator) و بعد هم ورودی ها.

ورودی های یک operator معمولا در دو طرف آن قرار دارند. مثلا فرض کنید در برنامه ی خود نوشته اید

p1 + p2;

در این جا ورودی های علامت جمع دو تا Point است.

بعضی از عمل گر ها یک ورودی دارند مثل !. برای این ها سمت ورودی مشخص شده است. مثلا برای همین ! باید ورودی در سمت راست ! بیاید. عمل گر ++ می تواند در دو طرف خود ورودی بگیرد.

حالا بیایید عمل گر + را برای نقطه تعریف کنیم. می توانید تعریف و استفاده ی آن را در کد زیر ببینید.

#include <iostream>
#include <cstdio>

using namespace std;

class Point{
    
    friend void set(Point*, int = 0, int = 0);

    private:

        int _x, _y;
        
        void setX(int);
        void setY(int);
    
    public:

        Point(int = 0, int = 0);

        int x() const;
        int y() const;

        void print();

};

Point::Point(int x, int y){
    set(this, x, y);
}

void Point::setX(int x){
    this->_x = x;
}

void Point::setY(int y){
    this->_y = y;
}

int Point::x() const{
    return this->_x;
}

int Point::y() const{
    return this->_y;
}

void Point::print(){
    printf("(%d, %d)", this->x(), this->y());
}

void set(Point *point, int x, int y){
    point->setX(x);
    point->setY(y);
}

Point operator+(Point p1, Point p2){
    return Point(p1.x() + p2.x(), p1.y() + p2.y());
}

int main(){
    Point p1(54, 12);
    Point p2(4, 23);
    Point pointsSum = p1 + p2;
    pointsSum.print();
}

به همین ترتیب می توانید عمل گر های بقیه ی عمل گر ها را برای Point تعریف کنید.

تمرین:

۱. عمل گر های *، / و ... را برای Point تعریف کنید (هم ضرب دو Point و هم ضرب یک Point در یک عدد).

۲. عمل گر های مقایسه (=، !=، <، > و ...) را برای Point تعریف کنید. برای عمل گر های کوچک تر و بزرگ تر ابتدا مؤلّفه ی x و سپس مؤلفّه ی y را با هم مقایسه کنید.

فعلا نمی توانید عمل گر های +=، -= و... را پیاده سازی کنید. جلسه ی بعد با طرز تعریف این عمل گر ها نیز آشنا خواهید شد.

فعلا همین عمل گر ها کافی است. بعدا (بعد از این که کمی بیشتر با تعریف عمل گر ها آشنا شدیم) عمل گر های بیشتری را تغییر خواهیم داد.

موفق باشید!