الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سؤال حول Operator & This

بدأه soufianosse في 5 فبراير 2010 · 10 رد · 1,175 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

كنت اتجول في النت فوجدت احد مواضيع الاخ Wajdy Essam حول Operator OverLoading

قرأت الموضوع فلم افهم بعض الامور

هدا الكود

#include <iostream>
using namespace std ;
class Counter
{
private :
  int x ;

public :
  Counter (int x)
  { this->x = x ; } // here another usage for this 

  Counter operator++ ()
  {
   x++;
   return *this ;
  }

  Counter operator++ (int)
  {
   Counter tmp(*this);
   x++;
   return tmp;
  }

  int getX()
  { return x ; }

};
int main ()
{
Counter c(1);
cout << "c = " << c.getX() << endl;

c++;
cout << "c++ : "  <<  c.getX() << endl;

++c;
cout << "++c : "  <<  c.getX() << endl;

Counter d = c ;  // here call to copy Constructor , we will explain it later
d = c++;
cout << "d = c++ \n";
cout << "c   : "  <<  c.getX() << endl;
cout << "d   : "  <<  d.getX() << endl;

d = ++c;
cout << "d = ++c \n";
cout << "c   : "  <<  c.getX() << endl;
cout << "d   : "  <<  d.getX() << endl;


return 0 ;
}

هدا الجزئ لم افهمه جيدا

  Counter operator++ ()
  {
   x++;
   return *this ;
  }


  Counter operator++ (int)
  {
   Counter tmp(*this);
   x++;
   return tmp;
  }

اولا لم افهم فلسفة Operator جيدا 50 % ما فهمته لو امكن من احد توضيح الامر بشكل مبسط

امر اخر لمادا هدا السطر

   return *this ;

من دون السطر سيتم زيادة x ونستدعي الدالة getX اليس صحيح ؟

اما هدا السطر فلم افهمه

Counter tmp(*this);

استعمل الـConstructor وامامه tmp و this

ممكن تفسير

فلو تخلينا عن الاسطر

Counter tmp(*this);
   return tmp;

فستبقى نفس النتيجة

المهم ادا استعمل postfix يكفي اضافة int ( المتغير المرسل ) الى Operator

لقد تهت في هده الامور

تم تعديل هذه المشاركة بواسطة soufianosse في 5 فبراير 2010 في 20:58

2
#2

السلام عليكم ...

سؤال جميل حقيقة, و ينم عن محاولة فهم للموضوع بشكل دقيق :)

قبل أن تبدأ في سبر أغوار كود الأخ وجدي, يجب أن تنظر إلى كيفية استخدام الـ postfix increment و الـ prefix increment في ++C/C, فالطريقة "الصحيحة" المتبعة لدى مبرمجي ++C,

هي أن يكون معنى تلك الـ operators التي تقوم بعمل overloading لها في الـ class الذي تقوم ببنائه, مشابه للمعنى الموجود للأنواع الأصلية في اللغة.

حسناً, كلام كبير و معقد في الأعلى :)

لاحظ التالي, مثلاً في قطعة الكود التالية:

int x = 0;
int i = 10;

x = ++i;
x = i++;

هل تستطيع معرفة قيمة x و i في كل لحظة من تنفيذ البرنامج؟ أعتقد أن تستطيع.

المهم, هو أن تلاحظ هو أنه في السطر التالي:

x = ++i;

قمنا بزيادة واحد على i, و القيمة التي تعود من i++ هي (i+1). و هذا بالضبط ما قام به الأخ وجدي:

  Counter operator++ ()
  {
   x++;
   return *this ;
  }

حيث قام بإعادة نسخة من الكائن, بعد عملية الإضافة!

بينما في الحالة الثانية:

x = i++;

فإن القيمة العائدة من ++i هي (i) فقط! و ليس i+1, بالتالي, فإن الفكرة هنا, أن i في الحقيقة تم زيادتها بمقدار واحد, بينما القيمة العائدة من الـ expression نفسها, عبارة عن i فقط!

لاحظ كيف يقوم الأخ وجدي بفعل ذلك:

  Counter operator++ (int)
  {
   Counter tmp(*this);
   x++;
   return tmp;
  }

أخذ نسخة من الكائن قبل الزيادة, ثم أضاف على الكائن نفسه 1, ثم أعاد النسخة الذي أخذها في الأول!

هذه هي الفكرة بكل بساطة. و لانسى أن this عبارة عن مؤشر للكائن الذي نقوم بتفيذ الـ operator عليه. و this* تعيد نسخة من الكائن لا أكثر.

تحياتي,

#3

شرا لك اخي فهمت this

لكن ما لم افهمه حتى الان في موضوع الاخ وجدي هي البداية

جمع كائنين ؟ زيادة كائن ؟ ما هي operator++

نجد ان operator كلمة محجوزة ، لكن ++ ؟

الا يكفي ان نقوم بكتابة Fonction عادية تقوم بزيادة قيمة x

ما اريد ان اوصله انني لم افهم من الاساس هده الكتابة operator ++ وزيادة الكائن او جمع كائين

تم تعديل هذه المشاركة بواسطة soufianosse في 5 فبراير 2010 في 22:28

#4

يمكن السؤال موجه للاخ خالد ، لكن لامانع من " اللقافة " ،

الهدف من تطبيق Operators على كائن معين Object ، هذا الكلام ذكره الاخ خالد في بداية رده السابق ، وهو أنك تستطيع أن تطبق نفس العمليات التي تجري على متغير من نوع int مثلاً، على كائن ما .

تستطيع أن تستغني عن كثير من هذه Operators وتكتفي بكتابة functions، لكن Operators في السي بلس تعطيك تحكم أفضل ومقروئية في بعض الاحيان لكودك .

خذ مثلاً كائن من نوع BigInteger ، وذلك لتمثيل صنف معيّن يستوعب أعداد أكبر من النوع العادي int ، سيبدو الكود وكأنك تتعامل مع متغير بسيط primitive :

BigInteger a("1000000");
BigInteger b("1000000");

std::cout << a+b;

BigInteger c = (a--) * b ; 
BigInteger d = c / ( 2 ) ;

std::cout << d ;

ولو كنت مبرمج جافا .. فانه لايوجد أمامك الا كتابة functions لتمثيل تلك العمليات :

BigInteger a("1000000");
BigInteger b("1000000");

std::cout << a.add(b);

BigInteger c;
c.setInteger( (a.sub(1) ).mult ( b ) ) ;
BigInteger d;
d.setInteger(c.div( 2 ) );
std::cout << d ;

الخلاصة أن استخدامك لهذه Operators تجعل برنامج جميل عندما تريد استخدام الكلاس ، وبشع عندما تريد كتابة الكلاس ، والخيار لك ،

مبرمجي السي بلس عموماً يستمتعون باستخدام Operators بدلاً من Functions العادية .

تم تعديل هذه المشاركة بواسطة الشمري في 6 فبراير 2010 في 01:43

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#5

شكرا لتدخلك اخي " الشمري "

لكن ربما لم تفهم قصدي انا لا اتكلم عن ++ العادية فهده الامور معروفة

انا اتكلم عن دور الكلمة المحجوزة operator ومادا تعني ++operator

ادا رجعنا لهدا الكود

 Counter operator++ ()
  {
   x++;
   return *this ;
  }

يمكن ان نكتب هكدا وسيكون لهما نفس الدور

#include <iostream>

using namespace std ;
class Counter
{
private :
  int x ;

public :

  Counter():x(0)
  {
   x++;

  }

  int getX()
  { 
      return x;

       }

};

int main ()
{

Counter c;

cout << "c : "  <<  c.getX() << endl;

    return 0;
}

ادن ما الفرق ؟

لو كانت هناك امتلة سيكون الامر جد واضح بادن الله

تم تعديل هذه المشاركة بواسطة soufianosse في 6 فبراير 2010 في 02:25

#6

كل ما تستطيع أن تفعله باستخدام Operators تستطيع أن تكتبه باستخدام functions عادية .. يعني الموضوع مسألة اذواق .. حسب ما أعلم .

لذلك ، اذا كان السؤال مالفرق ؟ فالجواب لا فرق ! فالنتيجة واحدة وان اختلفت الطرق ، ولكن هذه المعاملات أراها مناسبة لتوحيد أسلوب وطرق العمل فكلنا نعرف أنه لزيادة شيء ما نستخدم العلامة " + " ، بغض النظر عن هذا الشيء ، بينما لو استخدمت function فممكن يكون اسمها " add " أو "Add" أو "increase " .. الخ ، فتكون كمبرمج في حيرة من أمرك اذا لم تطّلع على وثائق الكود ، وستنسى أسماء functions بعد مدة من استعمالها .

هذا ما أعرفه .. وقد يوجد أسرار أخرى غائبة .. أجهلها .

هذا مثال مبني على مثال الاخ وجدي ، يستخدم Operators في كائن ـ و function في كائن آخر

#include <iostream>
using namespace std ;
class Counter
{
private :
  int x ;

public :
  Counter (int x)
  { this->x = x ; } // here another usage for this 

  Counter operator++ (int)
  {
   Counter tmp(*this);
   x++;
   return tmp;
  }

  int getX()
  { return x ; }

};

class Counter2
{
private :
  int x ;

public :
  Counter2 (int x)
  { this->x = x ; } // here another usage for this 


  Counter2 incrementAfter()
  {
   Counter2 tmp(*this);
   x++;
   return tmp;
  }

  int getX()
  { return x ; }

};


int main ()
{
Counter c(1);
cout << " c = " << c.getX() << endl;

c++;
cout << " c++ : "  <<  c.getX() << endl;

Counter2 f(1);
cout << "\n f = " << f.getX() << endl;

f.incrementAfter();
cout << " f++ : " << f.getX() << endl;

std::cin.get();
return 0 ;
}

على العموم ، ان كنت تسأل عن شيء آخر ولم أوضحه بشكل جيد فلا تستغرب .. فأنا سيء في مضمار " توصيل الفكرة" .. :) ، وشكراً لك على طريقتك في طرح السؤال .. نادراً مانجد سؤال بهذا الشكل هذه الايام .

تم تعديل هذه المشاركة بواسطة الشمري في 6 فبراير 2010 في 03:04

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#7

شكرا لك فهمت الامر الان لكن امرا اخر مازال يدور في رأسي في كود الاخ وجدي

هنا بالتحديد

 Counter operator++ ()
  {
   x++;
   return *this ;
  }


  Counter operator++ (int)
  {
   Counter tmp(*this);
   x++;
   return tmp;
  }

الـreturn الى من ؟ لا ارى اي مستقبل للقيمة المرجعة

تعديل قيمة x لا يعتمد على القيمة المرجعة

بعد امر الاستدعاء لا نجد سوى امر الطباعة cout واستدعاء الدالة ()getX عبر الكائن c

ادن الى من الـreturn

#8
اقتباس
ما اريد ان اوصله انني لم افهم من الاساس هده الكتابة operator ++ وزيادة الكائن او جمع كائين

فى لغات الدوت نت على سبيل المثال الرقم هو كائن من نوع Int32 هذا النوع له دوال تتيح لك اضافة و طرح و ضرب و القسمة منه و عليه لذا اذا افترضنا اننا سنقوم بصنع كائن مشابه لهذا النوع سيبدو كالتالى

struct Int32
{
	Int32(int i) : _n(i) {};

	const Int32 operator+(const Int32& i) const
	{ return Int32(i._n + _n); }

	Int32& operator+=(const Int32& i)
	{
		_n += i._n;
		return *this;
	}

private:
	int _n;
};

النوع السابق يمثل النوع Integer بمساحة 32bit الأن سنقوم بإنشاء نسخه منه كالمعتاد:

Int32 x = 10;

الأن نريد اضافة 5 للنوع x لذا يمكنك كتابة الكود التالى

x = x + 5;

الكود السابق هو الطبيعى و الذى يتم استخدام فى العاده و يمكنك الحصول على نفس التأثير بكتابة الكود التالى:

x = x.operator+(5);

فى الواقع المعامل ما هو إلا داله (داخل النوع) و التى لها صيغه مختلفه فى الإستدعاء (من جانبك انت) حيث ان المترجم فعليا يقوم بإبدال الصيغه الرياضيه بصيغه الدوال لإن المعامل هو داله لها اسلوب خاص فى التصريح عنها.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 6 فبراير 2010 في 07:17

مدونتي: C++ Tips and Tricks

#9

السلام عليكم ،

أري انك مرتبك فقط في لماذا استخدام تحميل زائد operator overloading و عدم استخدام الطريقة العادية في الزيادة x++ ، قس ذلك اخي علي تحميل [] في المصفوفات و << في دالة الاخراج cout<< :) .

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

#10
 Counter operator++ ()
  {
   x++;
   return *this ;
  }


  Counter operator++ (int)
  {
   Counter tmp(*this);
   x++;
   return tmp;
  }

الناتج سوف يهمل اذا لم يكن هناك مكان holder لحفظ القيمه الراجعه ..

c++ ; // here return value will igonre
++c ;  // again return value will ignore

// as we learn, there is no difference between postfix and prefix increment when they used alone in statement

أما اذا كانت هناك assignment مثلا :

object = c++ ; // postfix calling
object = ++c ; // prefix calling

فالobject سيحمل القيمة الجديده الراجعه من الدالة ،،

بالتوفيق،

تم تعديل هذه المشاركة بواسطة Wajdy Essam في 6 فبراير 2010 في 08:33

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#11

اصبح الامر واضحا الان

بارك الله فيكم

مواضيع مشابهة