operator overloading - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

operator overloading

+2 امتیاز
سلام دوستان. میشه  مفهوم operator overloading رو توی سی پلاس پلاس وقتی که در کلاس استفاده میشه رو  توضیح بدین. اینکه operator چرا توی یک کلاس استفاده میشه؟ ممنون.
سوال شده شهریور 9, 1393  بوسیله ی Pashmak (امتیاز 644)   8 15 31
دوباره تگ گذاری شد مهر 9, 1393 بوسیله ی BlueBlade

1 پاسخ

+3 امتیاز
 
بهترین پاسخ

operator overloading یعنی کاری کنیم که کلاس مثل یک متغیر معمولی عمل کنه  ,و عملیات های مثل  +- [] >> ,.... روش کار کنه . 

operator های موجود در ++C  واین که کدوم ها قابل overload شدن هستند رو میتونید از این لینک ببینید .

نحوه تعریف operator ها کاملا مثل توابع هست 

return_type operator_name (inputs);

مثلا فرض کنید که یک کلاس دارید که داخلش یک وکتور ذخیره شده : 

class A
{
public:
	A(std::initializer_list<int> data) : data_(data){}
        A(){}
private:
	std::vector<int> data_;
};

 

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

	A obj = {1,2,3,4};
        std::vector<int> data;
	obj<<data;

برای این که این کار قابل انجام باشه باید operator <<  که یک ورودی از نوع وکتور داره رو داخل کلاس بنویسید به این شکل  :

#include <vector>
#include <initializer_list>
#include <iostream>
class A
{
public:
	A(std::initializer_list<int> data) : data_(data){}

	A(){}

	A& operator<<( const std::vector<int>& data)
        {
		for (const auto& elem : data)
			this->data_.push_back(elem);
		return *this;
	}

	void print()
        {
		for (const auto& i : data_){
			std::cout << i << ' ';
		}
	}
private:
	std::vector<int> data_;
};



int main()
{
	A obj;
	std::vector<int> data = { 4, 5 };
	std::vector<int> data2 = { 1,2,3};
	obj << data<<data2<<data;//alan A mese cout kar mikone
	obj.print();// khorooji 4 5 1 2 3 4 5
}

 

نحوه کار cout هم کاملا به همین شکل هست cout خودش یک کلاس هست و >>operator براش به همین شکل overload شده . 

کار های زیادی میشه با operator ها انجام داد مثلا میشه کاری کرد که یک کلاس رو بشه با cout چاپ کرد این لینک رو ببینید : نحوه نوشتن کلاس با cout

یا این که کاری کنیم که کلاس کاملا مثل یک int عمل کنه ! : تولید اعداد بزرگ

یا کاری که کلاس string انجام میده که میشه 2 تا شی از std::string رو با هم +  زد .

یکی از کارهایی که خیلی زیاد انجام میشه اینه که کاری کنیم که کلاس مثل تابع  قابل صدا زدن باشه :

A obj;
obj(4,5);//mese function sheye A ghabele seda zadan hast

این کار با overload کردن () قابل انجامه :

class A
{
public:
	void operator()(int a, int b)
	{
		//...
	}
};

int main()
{
	A obj;
	obj(1, 4);
}

مثلا داخل این لینک.حذف نقاط تکراری   کلاس hash به این شکل تعریف شده :

 struct hash<Point2f>
    {
        size_t operator()(Point2f const& pt) const
        {
            return (size_t)(pt.x*100 + pt.y);
        }
    };

//be in shekl mishe estefade kard;

hash h;
h(Point2f(4,5));//mese seda zadan function

که برای استفاده از unordered_set ازش استفاده شده .

یکی دیگه از جاهایی که از operator overloading استفاده میشه سربارگذاری operator های new , delete[]  هست برای برگردوندن حافظه align شده 

و خیلی چیزای دیگه ....

داخل این تگ هم مثال هایی هست operator overloading

پاسخ داده شده شهریور 9, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد شهریور 11, 1393 بوسیله ی Pashmak
بابت پاسخ مفصلی که نوشتید ممنونم. اما چند جای کد رو مربوط به مثال اولی که نوشتید رو خوب نمی فهمم. به ترتیب اون ها رو پشت سر هم مینویسم اگخ وقت داشتید جواب بدید. اول از همه تفاوت vector با initializer_list جیه؟ که در بعضی جاها از vector و بعضی جاها از initializer_list استفاده کردید. دوم توی یکی از سازنده ها به صورت زیر نوشتید
A(std::initializer_list<int> data) : data_(data)
که ورودی اش یک لیستی به اسم data که از نوع int هست داید اما متوجه قسمت دومش نمیشم که نوشتید data_(data) این قسمت یعنی چی؟
سوم چرا تابع operator که نوشتید به صورت رفرنس هست. دلیل خاصی داره که از رفرنس استفده کردید؟ از طرفی کار این دستور this->data_.push_back(elem); چیه؟ و بعد از اون که نوشتید return *this یعنی ابتدای رشته رو برمیگردونه؟ چهارم اینکه چرا آرگومان ورودی برای operator از نوع const هست؟
ببخشید دیر جواب میدم دیروز نبودم .
وکتور یک آرایه است که طولش تغییر میکنه .
initializer list  به چند تا عنصر از یک نوع میگن که داخل {} هستن مثلا {1,2,4,5}
برای این این سازنده با initializer list رو نوشتم که
A obj = {1,2,3,4};

کارکنه
data_(data) یک روش هست برای مقدار دادن به اعضای کلاس
این لینک رو ببینید :http://goo.gl/AnrDx7
دلیل این که چرا refrence هست هم این جا توضیح دادم http://goo.gl/x1CVM4
ر this->data_.push_back(elem) میگه elem رو به آخر وکتور data_ که بصورت private تعریف شده اضافه کن.
this یک اشاره گر هست که به شی این کلاس اشاره می کنه (این جا *A) عملگر * مقدار این اشاره گر رو میده پس return *this شی این کلاس رو بر می گردونه .
دلیل این که ورودی const هست اینه که
1_مقدار های موقت هم بشه به تابع فرستاد
2_ از تغییر دادن مقدار جلوگیری کرد
3_ بعضی وقت ها هم کامپایلر میتونه از const بودن استفاده کنه و کد اسمبلی بهتری تولید کنه
این مثال رو ببینید
#include <iostream>

void foo(const int& a){
//dar khate badi eshtebhan bejaye ==gozashtim =
    if (a = 4)//inja chon const gozashtim error mide age nemizashtim error nemidad
    {}
}
int main()
{
    foo(3);//in kar mikone agar const nemizashtim error midad
}
بابت راهنماییتون خیلی ممنون :)
...