لماذا لا يسمح C++ بالتحويل غير الثابت في نسخة المرجع؟

StackOverflow https://stackoverflow.com/questions/1213418

  •  06-07-2019
  •  | 
  •  

سؤال

لدي عضوين من الأعضاء:

Node* prev() { return prev_; }
int value()  { return value_ }

يرجى ملاحظة عدم وجود معرفات const (لقد نسيتها، ولكن الآن أريد أن أعرف لماذا لن ينجح هذا).أحاول تجميع هذا:

Node(Node const& other) : prev_(other.prev()), value_(other.value()) { }

المترجم يرفض هذا.اعتقدت أن C++ يسمح بتحويل غير ثابت في معلمات الوظيفة، مثل:

{
   Foo(int bar);
}

Foo(const int bar)
{
   //lala
}

لماذا لا يسمح لي بفعل نفس الشيء مع مُنشئ النسخ؟معرف const يعني أنني أتعهد بعدم تغيير أي شيء، فلماذا يهم إذا حصلت على القيمة من مصدر ثابت أو غير ثابت؟

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

المحلول

وأنت لا تحاول أن تفعل غير CONST لتحويل CONST. كنت محاولة استدعاء اثنين من الأساليب التي لم يتم CONST في إشارة CONST (يدعو إلى السابق والقيمة). هذا النوع من العمليات يمنع منعا باتا من دلالات CONST.

وماذا يمكن أن تفعله بدلا من ذلك هو استخدام الحقول prev_ وvalue_ مباشرة. لأنه عضو في نفس النوع يمكنك الوصول حافظون والتي سوف تكون متاحة على الكائن CONST.

نصائح أخرى

اعتقدت أن C++ يسمح بتحويل غير ثابت في معلمات الوظيفة، مثل:

أنت تحاول أن تفعل العكس تمامًا:ثابت إلى غير ثابت.عند استدعاء دالة عضو غير ثابتة، سيقوم المترجم بربط التعبير (وهو عبارة عن ملف Node const إلى أ Node& لربط this المؤشر).وبالتالي سيتم إسقاط const - غير مسموح به لأنه سيستدعي دالة غير const على كائن const.

/* class Foo */ {
   Foo(int bar);
}

/* Foo:: */ Foo(const int bar)
{
   //lala
}

حسنًا، هذا الرمز شيء آخر تمامًا.تعلن عن دالة (منشئة) مرتين، والفرق الوحيد هو أن المعلمة في إحدى المرات تكون const، وفي مرة أخرى لا تكون كذلك.نوع الدالة هو نفسه في المرتين، وبالتالي لا يتعارضان (the const سيكون للمعلمة تأثير فقط داخل نص الوظيفة محليًا - ولن يحدث أي فرق للمتصل).بالإضافة إلى ذلك، لا يحتوي هذا الرمز على أي استدعاء (بافتراض أن الكتلة الأولى موجودة ضمن وظيفة ما).

إذا كنت أتساءل:إذا كان الإصداران أعلاه متطابقين - فلماذا ليس كذلك أدناه؟وذلك لأن ما يلي يحتوي على مستوى آخر من المراوغة:أدناه، المرجع نفسه ( افضل مستوى) ليس ثابتًا (لا يمكنك وضعه const على مرجع نفسه مباشرة)، ولكن النوع المشار إليه هو const.في هذا الوقت، ثابت هو لا يتم تجاهلها في تحديد نوع الوظيفة.

/* class Foo */ {
   Foo(int &bar);
}

// different thing, won't work!
/* Foo:: */ Foo(const int &bar)
{
   //lala
}

وأنت على حق - على CONST يعني أنك وعد بعدم تغيير أي شيء. المترجم تبذل على الحفاظ على وعدك بعدم السماح لك لاستدعاء الأساليب على هذا الكائن الذي لا أنفسهم وعد بعدم تغيير أي شيء.

في إعلان المنشئ Node(Node const& other) وأعلن other حجة const. هذا يعني أنه يمكنك الاتصال فقط طرق const على ذلك.

وأنت تدعو other.prev() وother.value() من منشئ كلاهما أساليب غير const، وبالتالي مترجم يشكو.

وكما ذكر آخرون، كنت استدعاء الأساليب غير CONST على كائن CONST التي سوف المترجم لا تسمح.

وإصلاح بسيط في ذلك هو للاحتفال فقط وظائف جالبة الخاص بك كما CONST:

Node* prev() const { return prev_; }
int value()  const { return value_; }

لأنها لا تعديل الكائن؛ الآن يمكن أن يسمى مع كائن CONST. في الواقع، وهذا ربما ينبغي القيام به على أي حال بحيث يمكن للمستخدمين من فئة دعوة تلك حاصل مع كائنات CONST.

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

Node(Node const& other) : prev_(other.prev()), value_(other.value()) { }

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

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