سؤال

أحاول خلق am ثابتة نوع (الطبقة) في C++ ،

لقد جعلت من ذلك أن جميع أساليب "الملقب وظائف الأعضاء" لا تعديل موضوع عودة مثيل جديد بدلا من ذلك.

أنا على التوالي عبر مجموعة من القضايا ، ولكنها جميعا تدور حول أنواع المراجع في C++.

أحد الأمثلة على ذلك هو عند تمرير المعلمات من نفس نوع الفئة بالإشارة:

Imm Imm::someOp( const Imm& p_im ) const
{
   ...
   p_im = p_im.someOtherOp(); //error, p_im is const, can't modify it!
   ...
}

الخطأ سببه تمرير القيمة المرجعية.إذا بدلا من ذلك, لقد كان يمر إشارة قيمة ، ثم خط الخطأ أعلاه لن يكون من الخطأ!

النظر في Java/C# مثلا

class Imm
{
    ...
    Imm someOp( Imm p_im )
    {
        ....
        p_im = p_im.someOtherOp(); //ok, you're not modifying the 
                 //original object, just changing the local reference
        ....  
    }
    ....
}

كيف يمكن أن أفعل شيئا من هذا القبيل في C++?وأنا أعلم أنني يمكن استخدام المؤشرات ولكن ثم أركض في كل إدارة الذاكرة الفوضى.أنا لا أريد أن تقلق حول من يملك مراجع إلى الكائنات.

ومن الناحية المثالية كنت ترغب في تصميم فئة أن تكون ثابتة مثل السلاسل في بيثون;يمكنك استخدامها من دون أن يلاحظ أي وقت مضى أو حتى عندما يعرفون أنهم غير قابل للتغيير ، وأنها لا تتصرف كما هو متوقع;أنها تعمل فقط.

تحرير

بالطبع لا يمكن أن تحصل من حوله عن طريق تمرير حسب القيمة أو باستخدام متغير temp (وهو ما أفعله حاليا).ما أنا أسأل عن "كيفية تمرير إشارات من حيث القيمة في C++"

أنا أتوقع الإجابة تدور حول شيء في المحكمة الخاصة بلبنان ، أنا أبحث حاليا في smart_ptr الأسرة من القوالب.

التحديث

شكرا على الردود أنا أدرك أنه ليس هناك هروب من المؤشرات.(انظر بلدي سؤال آخر, الذي هو في الحقيقة المتابعة على هذا)

هل كانت مفيدة؟

المحلول

في Java و C#, كنت لا حقا التعامل مع إشارة - هم أكثر مثل مقابض أو مؤشرات.مرجع في C++ هو حقا اسم آخر الكائن الأصلي ، لا مؤشر إلى ذلك (على الرغم من أنه قد يكون تنفيذها مع المؤشر).عند تعيين القيمة إلى مرجع ، يتم تعيين إلى هدف في حد ذاته.هناك التباس في ذلك تهيئة إشارة يمكنك استخدام = حرف, بل هو التهيئة ليست مهمة.

 Imm im, im2, im3; 
 Imm &imr = im;  // initialize a reference to im
 imr = im2; // assign im2 to imr (changes the value of im as well)
 Imm *imp = &im; // initialize a pointer to the address of im
 imp = &im3; // assign the address of im3 to imp (im is unnaffected);
 (*imp) = im2; // assign im2 to imp (modifies im3 as well).

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

 struct ImmRef
 {
     Imm &Ref;
     ImmRef(Imm &ref) : Ref(ref) {}
 };

نلاحظ أيضا أن const تطبيق إشارة يجعل يشار إلى كائن ثابت لا إشارة.المراجع دائما const.

نصائح أخرى

ليست مهمة ، بحكم التعريف ، وليس ثابت العملية ؟

يبدو أنك تحاول تعيين شيء const مرجع تماما الهزائم فكرة const المرجعية.

أعتقد أنك قد تكون تبحث عن مؤشر بدلا من إشارة.

أنها لا تعمل مثل هذا في C++.

عند تمرير مرجع إلى كائن فعلا تمرير عنوان في الذاكرة من وجوه.إشارات لا يمكن إعادة يجلس إلى كائنات أخرى سواء ، وبالتالي C++ القول المأثور "الإشارة هو كائن." لديك لجعل نسخة إلى تعديله.جافا سوف تفعل ذلك من وراء الكواليس بالنسبة لك.C++, عليك فقط نسخ ذلك.

لم تنسى أن تعيين طريقة الاتصال const?

تحرير:حتى مع const ثابت.

ربما عليك أن تفعل شيئا مثل

Imm & tmp = p_im.someOtherOp();

ثم مواصلة العملية على متغير tmp.

إذا قمت بتعيين متغير أو المعلمة const و أنت فقط لا يمكن تعيين إلى ذلك.

تحقق من هذا أن تعرف عن مؤقتة عمر http://herbsutter.wordpress.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

Imm Imm::someOp( const Imm& p_im ) const
{
   ...
   //Imm& im = p_im.someOtherOp();       // will *not* work
   const Imm& im = p_im.someOtherOp();   // will work, but you get a const reference
   ...
}

ولكن يمكنك استخدام دفعة::shared_ptr

shared_ptr<Imm> Imm::someOtherOp() const
{
  shared_ptr<Imm> ret = new Imm;
  ...
  return ret;
}

shared_ptr<Imm> Imm::someOp(const share_ptr<Imm>& p_im) const
{
  shared_ptr<Imm> im = p_im->someOtherOp();
}

تحتاج إلى إجراء نسخة جديدة الواردة الحجة.يمكنك أن تفعل ما تريد في عدة طرق مشابهة:1) هل يمكن أن تمر القيمة:

Imm Imm::someOp( Imm im ) const {
   im = im.someOtherOp();      // local im is a copy, original im not modified
   return im;                  // return by value (another copy)
}

أو 2) يمكنك تمرير-بالرجوع وتقديم نسخة صراحة:

Imm Imm::someOp( const Imm & im ) const {
   Imm tmp = im.someOtherOp(); // local tmp is a copy
   return tmp;                 // return by value (another copy)
}

كل النماذج هي ما يعادلها.

C++ لديه شيء أفضل من ثابتة أنواع—const.نوع واحد يمكن أن تكون قابلة للتغيير أم لا اعتمادا على الاحتياجات الخاصة بك.وقال ان هناك فائدة أنماط التعامل مع قصيرة العمر (شبه)نسخ:

void f(const X &x) {
  // Trivial case: unconditional copy
  X x2=transform(x);
  // Less trivial: conditional copy
  std::optional<X> maybe;
  const X &use=need_copy ? maybe.emplace(transform(x)) : x;
  use.go();  // whichever, x or *maybe
}  // *maybe destroyed iff created, then x2 destroyed

std::unique_ptr يمكن أن تستخدم بطريقة مماثلة قبل C++17 ، على الرغم من أن وظيفة ثم يمكن بالطبع رمي std::bad_alloc.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top