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

مشكلة خفية شغلتني لساعات

بدأه Islamic_Empire في 27 نوفمبر 2009 · 3 رد · 818 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

إخوتي هذا جزء من برنامج كنت أعمل عليه وواجهتني مشكلة أثناء استخدام هذا الصنف فيما بعد

#include <iostream>

using namespace std;

class A
{
private:
int number;
public:
A() {}
A(int n) : number(n) {} 

void operator+=(const A &temp) 
{
  number = number + temp.number ;
  cout << "the value of temp " << temp.number << endl;
}

void print()
{ 
  cout << number << endl;
}
};



void main()
{
A object(2);
object += object;
object.print();
}

طبعا المشكلة في operator+= أننا أخذا reference لنفس الكائن ولكن بعد التعديل على الكائن تغير ال reference أيضا والنتيجة أن أي استخدام لاحق للمتغير temp سيؤدي إلى نتائج كارثية

الحل :

هل أزيل ال reference أم هناك حل أفضل ؟

وسؤال إذا تغيرت قيمة temp فما فائدة const keyword أصلا

#2

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

لا أرى ماهي المشكلة التي تحصل في الكود. هل من الممكن أن توضح أكثر,

العملية معرفة بشكل كامل,

لاحظ معي ما يحصل:

object += object;

هذا السطر يخبر المترجم بأن يستخدم الـ operator المسمى =+, فيتم تنفيذ التالي:

number = number + temp.number ;

كل ما في الأمر, أن العدد الآخر هو نفس المتغير number في الكائن الذي على يسار الـ operator المسمى =+, و هذا لا ضرر منه, لأن عملية الـ evalution تحصل للطرف الأيمن, ثم يتم اسناد القيمة إلى الطرف الأيسر.

حتى الآن لا مشكلة, أعتقد أنك تقصد بالمشكلة السطر التالي:

  cout << "the value of temp " << temp.number << endl;

temp عبارة عن reference, بعنى آخر, هو عبارة عن قيمة تخبرنا أين هو الكائن temp و متغيراته, بالتالي, فإن ما سيتم طباعته هو number الموجودة في الكائن الذي يقع على يسار عملية الـ assignment,

و الذي هو في هذه الحالة الكائن المشار إليه في temp.

أما const فتعنى أن الكائن لا يمكن أن يتم تعديله, إلا قراءة متغيراته, و تطبيق الدوال المنتهية بـ const, أو الـ constant member functions.

و في المثال الذي طرحته, temp لا يتم تعديله, كل ما يحصل هو قراءة المتغير temp.number

هل هناك مشكلة لا أراها :)

تحياتي,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 28 نوفمبر 2009 في 03:56

#3

أخي temp يتم تعديله بدليل أن قيمته تغيرت من 2 إلى أربعه , و السبب كما قلت أنه reference لنفس الكائن فأي تعديل سيحدثه operator=+ سيغير من قيمة A ومن قيمة temp أيضا

المشكلة ستظهر إذا استخدمت temp مرة أخرى في نفس الكود مثلا (وهو ما حدث معي) معتقدا أن قيمتها لم تتغير (ما زالت 2)

#4

السلام عليكم، عيد سعيد!...

المرجع temp هو const، وبالتالي فإن temp.number لا يمكن تغييره داخل دالة المعامل +=، ولكن مؤشر this ليس const ويمكن عن طريقه تغيير قيمة number حتى وإن كان لنفس الكائن.

بعبارة اخرى، كون المؤشر لكائن معين const لا يعني عدم إمكانية تغيير صفات ذلك الكائن، ولكن يعني عدم إمكانية تغيير صفات ذلك الكائن عن طريق ذلك المؤشر تحديداً.

انظر هذا الكود مثلاً:

#include <iostream>

using namespace std;

class TheClass
{
public:
	TheClass()
	{
 	value = 0;
	}
	~TheClass()
	{
	}
	void print() const
	{
 	cout<<"Value is now: "<<value<<endl;
	}
	int value;
};

int main()
{
	TheClass tc;
	const TheClass& const_ref_tc = tc;
	TheClass& ref_tc = tc;

	tc.value = 10;
	const_ref_tc.print();
	ref_tc.value = 20;
	const_ref_tc.print();

	return 0;
}

وكما هو متوقع سيكون الناتج هو قيمتي 10 و 20.

من الجدير بالذكر هنا اللاحقة const لإجراء print، هذه اللاحقة يجب وجودها لكي يمكن استدعاء الإجراء عن طريق مرجع const، عدم إضافة const سيعطي خطئاً (على الأقل عند استخدام مترجم gcc)، ونص الخطأ هو الآتي:

passing `const TheClass' as `this' argument of `void TheClass::print()' discards qualifiers

أتمنى أن أكون قد ساعدت :)

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