التحميل الزائد للوظيفة المستندة إلى const عبر الوصول العام/المحمي

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

سؤال

(أعتقد) أعرف عن وظائف التحميل الزائد بناءً على الثبات:إذا كانت اللحظة ثابتة، فسيتم استدعاء الطريقة const، وإلا يتم استدعاء الطريقة غير الثابتة.

مثال (أيضا في com.ideone):

#include <iostream>

struct S
{
  void print() const { std::cout << "const method" <<std::endl };
  void print()       { std::cout << "non-const method" <<std::endl };
};

int main()
{
  S const s1;
  s1.print(); // prints "const method"
  S s2;
  s2.print(); // prints "non-const method"
  return 0;
};

لقد حاولت/حاولت الاستفادة من ذلك في الكود الخاص بي، ولكن واجهت بعض المشكلات عندما يكون const الأساليب المحملة بشكل زائد ليس لها نفس فئة الوصول.قد يكون أسلوبًا سيئًا، لكن هنا مثال يعكس فكرة إرجاع المراجع لتجنب النسخ والاستخدام const للحد من التعديلات غير المقصودة:

struct Color;
struct Shape
{
  double area;
};

class Geometry
{
public:
  // everybody can alter the color of the geometry, so 
  // they get a mutable reference
  Color& color() { return m_color; };

  // not everybody can alter the shape of the Geometry, so
  // they get a constant reference to the shape.
  Shape const& shape() const { return m_shape; };

protected:
  // derived classes can alter the shape, so they get 
  // access to the mutable reference to alter the shape.
  Shape & shape() { return m_shape; };

private:
  Shape m_shape;
  Color m_color;
};

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

// this one fails
void colorByArea() {
  for( Geometry g : geometryList )
  { g.color() = colorMap[g.shape().area]; }
}

// this one is a clunky workaround
void colorByArea() {
  for( Geometry g : geometryList )
  { 
    Geometry const& g_const = g;
    g.color() = colorMap[g_const.shape().area];
  }
}

فشل هذا (أو شيء مشابه) بسبب الخطأ التالي المفهوم إلى حد ما:

‘Shape& Geometry::shape()’ is protected 
  Shape & shape() { return m_shape; };

^ error: within this context
  g.color() = colorMap[g.shape().area];

(لقد طرحت مثالًا مبسطًا قليلاً غير مجمع على com.ideone.)

أفهم (إلى حد ما) سبب حدوث ذلك:g ليس const ومن ثم من المفترض أن يتم استدعاء الشكل غير الثابت () ، وهو حماية، - ولكن من الواضح أن هذا فشل.

لذلك أعتقد بلدي سؤال يكون:هل هناك طريقة للحصول على نوع من "الرجوع" إلى وظيفة const إذا لم يكن من الممكن الوصول إلى وظيفة غير ثابتة؟

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

المحلول

هل هناك طريقة للحصول على نوع من "الرجوع" إلى وظيفة const إذا لم يكن من الممكن الوصول إلى وظيفة غير ثابتة؟

لا؛يحدث حل الزائد قبل التحقق من الوصول.

وهذا ليس مجرد أسلوب سيئ؛إنه تصميم سيء.وظيفة getter العامة هي مختلفة من الناحية المفاهيمية من وظيفة محمية تتيح للتعليمات البرمجية التي لديها معرفة بالأجزاء الداخلية تعديل الحالة الداخلية للكائن.بشكل عام، لا تحتاج الوظيفتان إلى أنواع إرجاع ذات صلة.ولذلك لا ينبغي أن يكون لهم نفس الاسم.

نصائح أخرى

يمكنك استخدام const_cast للسماح باستدعاء إصدار const كـ:

int main()
{
  S s2;
  const_cast<const S&>(s2).print(); // prints "const method"
  return 0;
};

ولكن سيكون من الأفضل/الأبسط إعادة تسمية إحدى الطرق.

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