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

القيمه المعاده من الدوال

بدأه C++er في 15 يونيو 2011 · 13 رد · 939 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

إليكم سؤال ينشط الهمم قليلا:

ما الفرق بين الدالتين فى الكود التالي: (مع التفصيل إن أمكن):

#include <string>
using std::string;

string getString1()
{
   string s = "string value";
   return s;
}

string getString2()
{
   return string("string value");
}

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

تم تعديل هذه المشاركة بواسطة محمد علاء الدين في 15 يونيو 2011 في 16:11

2

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

#2

التعبير الاول يرجع نسخه من السترينغ named instance بينما الثاني يرجع نسخه غير مسماه anonymous instance

التعبير الاول يمكن اسناده الى reference بينما الاستدعاء الثاني لا يمكن اسنادة الى reference

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#3
اقتباس
التعبير الاول يرجع نسخه من السترينغ named instance بينما الثاني يرجع نسخه غير مسماه anonymous instance

إجابه صحيحه - توجد اجابه أخرى أكثر دقه.

اقتباس
التعبير الاول يمكن اسناده الى reference بينما الاستدعاء الثاني لا يمكن اسنادة الى reference

إجابه خاطئه، كلاهما يعود بنسخه تستطيع تخزينها داخل string reference حيث فى كل الأحوال يتم نسخ المحتويات لموقع جديد بسبب معامل التساوي او temporary object.

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

تم تعديل هذه المشاركة بواسطة محمد علاء الدين في 16 يونيو 2011 في 00:11

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

#4

الجافا خربتني

بس لاحظ اني لما استخدم named instance الكود ده حيشتغل

#include <iostream>

class A{


      public:
             int i;
             A(int i){
                   (*this).i = i ;
                 }
             A& addA(A a){
                     A i =  A(a.i + (*this).i);
                      return i;
             }
             int getI(){return i ;}

      };

      int main(){

          A a = A(10);
          A b = A(20);
          A& c = a.addA(b);
          std::cout <<  c.getI()<< std::endl;
          return 0 ;
          }

بس لما بتستخد anonymous instance مش حيرضىى

#include <iostream>

class A{


      public:
             int i;
             A(int i){
                   (*this).i = i ;
                 }
             A& addA(A a){
                      return A(a.i + (*this).i);

             }
             int getI(){return i ;}

      };

      int main(){

          A a = A(10);
          A b = A(20);
          A& c = a.addA(b);
          std::cout <<  c.getI()<< std::endl;
          return 0 ;
          }

وبيقول

 C:\Users\user\Desktop\Untitled1.cpp In member function `A& A::addA(A)': 
12 C:\Users\user\Desktop\Untitled1.cpp invalid initialization of non-const reference of type 'A&' from a temporary of type 'A'

تم تعديل هذه المشاركة بواسطة mental-driller في 16 يونيو 2011 في 20:03

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#5

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

يا جماعة الخير ربما أخطأت الفهم و لكن:

اقتباس
التعبير الاول يمكن اسناده الى reference بينما الاستدعاء الثاني لا يمكن اسنادة الى reference

في الحالتين لا يمكن الإسناد إلى reference, لسبب بسيط هو أن المتغيرين تنتهي حياتهما بمجرد الخروج من الـ scope, و بالتالي فكل ما لديك عبارة عن dangling reference لمكان لا معنى له في الذاكرة. عموماً, لا يمكن أصلاً إسناد متغير مؤقت إلى مرجع و لكن هذا ممكن في حالة المؤشرات و لكنه خاطئ أصلاً. هذا أصبح ممكناً مع الـ RValue Reference في المقاييس الجديدة و لكن لا يتم استخدام الـ rvalue reference بشكل مباشر في الغالب.

1
#6
Khaled.Alshaya كتب:

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

يا جماعة الخير ربما أخطأت الفهم و لكن:

في الحالتين لا يمكن الإسناد إلى reference, لسبب بسيط هو أن المتغيرين تنتهي حياتهما بمجرد الخروج من الـ scope, و بالتالي فكل ما لديك عبارة عن dangling reference لمكان لا معنى له في الذاكرة. عموماً, لا يمكن أصلاً إسناد متغير مؤقت إلى مرجع و لكن هذا ممكن في حالة المؤشرات و لكنه خاطئ أصلاً. هذا أصبح ممكناً مع الـ RValue Reference في المقاييس الجديدة و لكن لا يتم استخدام الـ rvalue reference بشكل مباشر في الغالب.

انا فاهم قصدك انه الautomatic variable بيتم تدميره لانه بيتم بنائه على الstack

بس لما يكون عندك named instance ممكن عمل copying لقيمة المتغير الى reference ، او لا؟

شوف الكودين اللي انا كاتبهم ، في كل واحد انا بسند القيمة المرجعة من الدالة الى reference الحالة بتاع الanonymous reference هي اللي بتدي خطأ

A& c = a.addA(b);

A& addA(A a){
                     A i =  A(a.i + (*this).i);
                      return i;
             }

A& addA(A a){
                      return A(a.i + (*this).i);

             }

تم تعديل هذه المشاركة بواسطة mental-driller في 17 يونيو 2011 في 05:31

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#7
Khaled.Alshaya كتب:

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

يا جماعة الخير ربما أخطأت الفهم و لكن:

في الحالتين لا يمكن الإسناد إلى reference, لسبب بسيط هو أن المتغيرين تنتهي حياتهما بمجرد الخروج من الـ scope, و بالتالي فكل ما لديك عبارة عن dangling reference لمكان لا معنى له في الذاكرة. عموماً, لا يمكن أصلاً إسناد متغير مؤقت إلى مرجع و لكن هذا ممكن في حالة المؤشرات و لكنه خاطئ أصلاً. هذا أصبح ممكناً مع الـ RValue Reference في المقاييس الجديدة و لكن لا يتم استخدام الـ rvalue reference بشكل مباشر في الغالب.

اخي الكريم ما فأئده ال stack size التي نحددها بال return اذاً ؟؟ في حاله ان لا اهميه لل return type لل function اذا لا يمكن ان نعمل داله بال سي تعيد قيمه ؟

#8

أخي mental-driller, ما دام أنك تحاول إسناد متغير انتهت حياته إلى مرجع فما تقوم به غير صحيح. اللغة تحميك من الوقوع في المحظور من خلال منع إسناد القيمة العائدة من الدالة إلى مرجع إذا كانت تلك القيمة A مثلاً. أما إن كان النوع العائد عبارة عن مرجع &A ففي تلك الحالة أنت المسؤول عن ضمان الصلاحية. بمعنى أنك في الحالة التي تقول أن كودك صحيح أعدت مرجعاً لكائن قد انتهت حياته أصلاً بمجرد الخروج من الدالة. اللغة تسمح بفعل هذا الشيء رغم أن هذه الحالة خاطئة, لأنك قد تعيد أحد أعضاء الكائن و متغيرات الكائن(كالعدد الصحيح في مثالك) لا تنتهي بمجرد الخروج من الدالة و إنما بانتهاء حياة الكائن نفسه.

عذراً أخي علي لم أفهم نقطتك, هل من الممكن أن توضح أكثر؟

#9

ردي هو تسأل بالنسبة لردك

اقتباس

في الحالتين لا يمكن الإسناد إلى reference

وانا في الكود الذي كتبته ، حاولت ان اوضح انه يمكن الاسناد الى ريفيرنس في حالة named instance

واللي هو كان اصلا تعقيب لرد الاخ محمد علاء الدين

ملاحظة: انا فعلا عملت كومبايل للكود ويستغل في حالة named instance ولا يعمل في حالة anonymous instance

تم تعديل هذه المشاركة بواسطة mental-driller في 18 يونيو 2011 في 11:27

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#10

السلام عليكم

حسب فهمي أظن أن الموضوع له علاقة بال return value optimisation .

الدالة الأولى تستعمل متغير مسمى كقيمة مرجعة بينما الدالة الثانية تعتمد على متغير غير مسمى حيث تقوم باستدعاء مشيد الكلاس string .

أيضا سيكون هناك فرق في السرعة بسبب المراحل التي تمر منها كل دالة (الدالة الثانية ستكون اسرع).

1
#11
اقتباس
حسب فهمي أظن أن الموضوع له علاقة بال return value optimisation .

+1

الهدف من السؤال كان التعريف بمفهوم الـ Return value optimization RVO و الـ Named return value optimization NRVO و كيف يقوم المترجم فى التعامل معهم عند إعادة كائن بالقيمه.

اقتباس
إجابه خاطئه، كلاهما يعود بنسخه تستطيع تخزينها داخل string reference حيث فى كل الأحوال يتم نسخ المحتويات لموقع جديد بسبب معامل التساوي او temporary object.

كنت اقصد هنا &const string

اقتباس
لا يمكن أصلاً إسناد متغير مؤقت إلى مرجع و لكن هذا ممكن في حالة المؤشرات و لكنه خاطئ أصلاً

أخي خالد هل الكود التالي خاطئ:

#include <string>
using std::string;

string getString1()
{
   string s = "string value";
   return s;
}

string getString2()
{
   return string("string value");
}

int main()
{
   const string& s1 = getString1();
   const string& s2 = getString2();
}

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

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

#12

أخي محمد,

في مثالك الكود صحيح لأنك تقوم بإسناد كائن مؤقت حياته لا تنتهي بمجرد الخروج من الدالة, بينما إذا أعادت أي من الدالتين مرجعاً لنص فإن الكود يندرج تحت الـ undefined behavior. لاحظ أننا نتكلم عن هذا الأمر فقط في حالة المراجع الـ const بينما إذا كان الطرف الأيسر بالطبع مرجعاً فقط و ليس مرجعاً ثابتاً فهذا لا يجوز أيضاً.

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

1 −1
#13
Khaled.Alshaya كتب:

أخي محمد,

في مثالك الكود صحيح لأنك تقوم بإسناد كائن مؤقت حياته لا تنتهي بمجرد الخروج من الدالة, بينما إذا أعادت أي من الدالتين مرجعاً لنص فإن الكود يندرج تحت الـ undefined behavior. لاحظ أننا نتكلم عن هذا الأمر فقط في حالة المراجع الـ const بينما إذا كان الطرف الأيسر بالطبع مرجعاً فقط و ليس مرجعاً ثابتاً فهذا لا يجوز أيضاً.

اخي ماذا لو ارجعت struct يحتوي على array من ال chars اي نص ، لان يكون هنالك مشكله ايضاً لانني حددت حجم ال stack ، اروجو توضيح الفكره

#14
اقتباس
اخي ماذا لو ارجعت struct يحتوي على array من ال chars اي نص ، لان يكون هنالك مشكله ايضاً لانني حددت حجم ال stack ، اروجو توضيح الفكره

ممكن مثال توضيحي؟

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

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…