الشبكة العربية لمطوري الألعاب

خبير  سلوان الهلالي مشاركة 11

أعتقدت إن Item كلمة محجوزة أو إسم مستخدم لشيء ما في دوت نت...
وقد تأكدت عن طريق MSDN للتو إنه فعلاً إسم مستخدم في عدة اماكن وأجزاء, يا ترى هل هذه هي المشكلة؟

محترف مشرف عبد اللطيف حاجي علي مشاركة 12

أما في 21 شباط 2009 02:54 م، فقد تنهد سلوان الهلالي بارتياح وهو يرد:

أعتقدت إن Item كلمة محجوزة أو إسم مستخدم لشيء ما في دوت نت...
لقدت اقتربت من الجواب الصحيح جداً أخي سلوان ☺ . لكن هل تعرف أين تستخدم هذه الكلمة بالضبط؟ ولماذا الـ code التالي (جربه في مشروع جديد) لا يعطي أية خطأ مع أنه يستخدم نقس كلمة Item? 😒

int Item = 5; 

لقد جهزت أكثر من عشرة أسئلة ولا أطيق الانتظار حتى تجاوبوا على هذا السؤال لأعطيكم الذي بعده 😄

عبد اللطيف حاجي علي
مبرمج
In|Framez

محترف  انس مشاركة 13

سلام

حسنا لقد وجدت الخلل لكن قمت بالبحث في غوغل ... ساطرح الحل هنا و ادا اعتبرت الطريقة غشا ساقوم بلغائه

حسب   msdn





If your class is named 'Item' and has an indexer declared as this,
 you may get this error. A default indexer is given the name 'Item' 
in the emitted code, creating the conflict.


بعبارة اخرى لقد قمت بلقتراف الدنب نفسه ☺ ....

الكلاس  اسمه  Item ...  و لديك المؤشر this ك indexer ☺ ....   (يا عيني عن الترجمة ☺ )

اظنها الجواب الصحيح .



في 21 فبراير 2009 08:08 م، غمغم عبد اللطيف حاجي علي باستغراب قائلاً:

لقد جهزت أكثر من عشرة أسئلة ولا أطيق الانتظار حتى تجاوبوا على هذا السؤال لأعطيكم الذي بعده
اتمنى ان لا تكون كلها بالسي شارب 😄

محترف مشرف عبد اللطيف حاجي علي مشاركة 14

وفي 21 شباط 2009 11:12 م، ظهر شبح ابتسامة على وجه انس وهو يقول:

حسنا لقد وجدت الخلل لكن قمت بالبحث في غوغل ... ساطرح الحل هنا و ادا اعتبرت الطريقة غشا ساقوم بلغائه
لا، لا أعتبره غشاً وإلأ كنت أنا أكبر غشاش في العالم 😲 . إلا أن هذا يذهب بكثير من المتعة 😳 ، لذلك أتمنى أن نحاول الاعتماد على أنفسنا بادئ الأمر و اللجوء للوب في حال دعى الأمر لذلك ☺ . طبعاً يجب أن نفهم السبب تماماً ولا نكتفي بنسخ الحل كما هو 😒 . على كلٍ أنا قلت أنا هذا السؤال (والذي قبله) بسيط لأن حله موجود على الوب. لكني أعدك بأن أسئلتي لن تكون كلها بسيطة 😄 .

أما في 21 شباط 2009 11:12 م، فقد تنهد انس بارتياح وهو يرد:

بعبارة اخرى لقد قمت بلقتراف الدنب نفسه ....
لم أفهمك هنا؟ أين اقترفت نفس الخطأ؟ في السؤال الأول؟ 😳


في 21 شباط 2009 11:12 م، غمغم انس باستغراب قائلاً:

الكلاس  اسمه  Item ...  و لديك المؤشر this ك indexer ....   (يا عيني عن الترجمة )اظنها الجواب الصحيح .
ممم 😳 .. ساعتبر هذه الإجابة صحيحة، وإن كنت أتمنى لو شرحت قليلاً عن السبب ☺ .

على كلٍ السبب هو في طريقة C# في محاكاة عملية الـ index overloading حيث أن المترجم يقوم في الحقيقة بتعريف إجراء اسمه Item ومناداة هذا الإجراء عند عمل الـ indexing. أي أن الـ code التالي:

int this[int index]
{
   get { return 0; }
}

// Some other place
Test t = new Test();
int i = t[5];

يكافئ تماماً هذا الـ code:

int Item(int index)
{
    return 0;
}

// Some other place
Test t = new Test();
int i = t.Item(5);

الفارق الوحيد هو أن الأولى أجمل من ناحية الـ syntax 😄

بنفس الطريقة فإن C# تقوم بمحاكاة الـ properties عن طريق إجراءات تسمى بنفس اسم الـ property مع get_ أو set_ تسبقها. أي أن الـ code التالي سيعطي نفس الخطأ تقريباً:

private int _MyProperty;
public int MyProperty
{
	get { return _MyProperty; }
	set { _MyProperty = value; }
}
// محاكاة get من MyProperty
public int get_MyProperty()
{
	return _MyProperty;
}
// محاكاة set من MyProperty
public void set_MyProperty(int value)
{
	_MyProperty = value;
}

// في مكان آخر
Test t = new Test();
// السطر الأول يحاكى بالثاني
t.MyProperty = 5;
t.set_MyProperty(5);

int i;
// نفس الشي
i = t.MyProperty;
i = t.get_MyProperty();


إذا كان كان لديكم أي تساؤلات فأتمنى أن تفتحو موضوعاً جديداً لها وأعدكم بأني سأحاول شرحها أكثر ☺ .
حسناً نقطة لأنس ( مع تمنياتي أن تكون قد فهمت السبب 😄 )

عبد اللطيف حاجي علي
مبرمج
In|Framez

محترف مشرف عبد اللطيف حاجي علي مشاركة 15

يوم جديد، سؤال جديد
اللغة: C++
الصعوبة: متوسط
المطلوب: سبب الخطأ واقتراح طرق لحله
المشكلة:
المشروع يتألف من ملفين. الأول يدعى UserOutput.cpp ويحوي التالي:

#include 
#include 
#include 
template
void MinMax(const std::vector& arr, T& min, T& max)
{
    typedef std::vector::const_iterator iterator;
    min = std::numeric_limits::max();
    max = std::numeric_limits::min();
    for (iterator itr=arr.begin();itr!=arr.end();itr++)
    {
        if (*itr < min) min = *itr;
        if (*itr > max) max = *itr;
    }
    // Done!
}
void FormatMessage(const std::vector& arr)
{
    int min, max;
    MinMax(arr, min, max);
    wprintf(TEXT("Minimum of array is: %d\n")
            TEXT("Maximum of array is: %d\n"), min, max);
}
 
الملف الثاني يدعى Test.cpp و يحوي التالي:

#include 
int main()
{
    void FormatMessage(const std::vector& arr);        // Defined in UserOutput.cpp
    std::vector myArray;
    myArray.push_back(11);
    myArray.push_back(8);
    myArray.push_back(6);
    myArray.push_back(3);
    myArray.push_back(0);
    FormatMessage(myArray);
}
 
عند ترجمة الـ code باستخدام المترجم cl.exe و إعطاءه المحددات التالية:

/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "UNICODE" /FD /W0 /EHsc /MT
 
يظهر هذا الخرج:

1>Compiling...
1>UserOutput.cpp
1>.\UserOutput.cpp(9) : error C2589: '(' : illegal token on right side of '::'
1>        .\UserOutput.cpp(22) : see reference to function template instantiation
              'void MinMax(const std::vector<_Ty> &,T &,T &)' being compiled
1>        with
1>        [
1>            _Ty=int,
1>            T=int
1>        ]
1>.\UserOutput.cpp(9) : error C2059: syntax error : '::'
1>.\UserOutput.cpp(10) : error C2589: '(' : illegal token on right side of '::'
1>.\UserOutput.cpp(10) : error C2059: syntax error : '::'
 
هل يمكنك معرفة السبب؟ 😒

عبد اللطيف حاجي علي
مبرمج
In|Framez

موهوب  عبدالله الشمّري مشاركة 16

دعني أحاول أيضا ...

المشكلة والله أعلم هي بسبب أن الدالتين min و max معرّفتين سابقا في مكانٍ ما .. ممكن تكون معرفة في windows.h أو المكتبات القياسية القديمة للغة السي ..

لذلك المترجم يصاب بجنون .. لأنه ينظر للدالة min , و الدالة max على أنها دوال ليس لها علاقة بالـ std .

الحل :

الحل الذي أعرفه هو بالغاء تعريف min و max .. قبل استخدامها .. مثال :



#undef min
#undef max

template
void MinMax(const std::vector& arr, T& min, T& max)
{
    typedef std::vector::const_iterator iterator;
    min = std::numeric_limits::max();
    max = std::numeric_limits::min();
    for (iterator itr=arr.begin();itr!=arr.end();itr++)
    {
        if (*itr < min) min = *itr;
        if (*itr > max) max = *itr;
    }
    // Done!
}
void FormatMessage(const std::vector& arr)
{
    int min, max;
    MinMax(arr, min, max);
    wprintf(TEXT("Minimum of array is: %d\n")
            TEXT("Maximum of array is: %d\n"), min, max);
}

#define min 
#define max


😄

--
طالب - تخصص نظم معلومات .
--

محترف  انس مشاركة 17

لم اقل شيئا ☺

خبير  سلوان الهلالي مشاركة 18

لقد سبقني الأخ الشمري 😄
ولكن سأكتب الحل على كل حال.
 
الحل بالنسبة لي هو إضافة:


#define NOMINMAX
 
في بداية ملف: UserOutput.cpp
المشكلة كانت (كما أشار الشمري) إن هنالك تعريف preprocessor لـ min/max في ملف windef.h.

محترف مشرف عبد اللطيف حاجي علي مشاركة 19

قبل أن أعتبر هذا السؤال منتهياً وأتشدق بما أعرف كعادتي. هل يمكن لأحد أن يقول لي لماذا يعطي الـ code السابق (بعد تصحيحه باستخدام طريقة سلوان أو الشمري) عند ترجمته بنفس المحددات الخطأ التالي؟ مرة أخرى: كيف يمكن تصحيح الخطأ؟ أيضاً ماذا يعني هذا الخطأ بالضبط؟

1>Test.obj : error LNK2019: unresolved external symbol
             "void __cdecl FormatMessage(class std::vector<int,class> > const &)"
             (?FormatMessage@@YAXABV?$vector@HV?$allocator@H@std@@@std@@@Z) referenced in function _main

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير  سلوان الهلالي مشاركة 20

وفي 23 شباط 2009 02:34 م، قال عبد اللطيف حاجي علي متحمساً:

قبل أن أعتبر هذا السؤال منتهياً وأتشدق بما أعرف كعادتي. هل يمكن لأحد أن يقول لي لماذا يعطي الـ code السابق (بعد تصحيحه باستخدام طريقة سلوان أو الشمري) عند ترجمته بنفس المحددات الخطأ التالي؟ مرة أخرى: كيف يمكن تصحيح الخطأ؟ أيضاً ماذا يعني هذا الخطأ بالضبط؟

السبب هو وجود إجراء بنفس الإسم في windows.h, والحل هو إما تغيير إسم الإجراء لشيء آخر, أو تلافي إضافة windows.h في ملف UserOutput.cpp ولكن إستبدال:

TEXT("...")
 
بـ

L"..."
 
في الحقيقة, TEXT معرّف بهذا الشكل في ملف winnt.h:

#define __TEXT(quote) L##quote 
 
😏