سؤال

أحاول أن أتعلم لغة C++، لذا سامحني إذا كان هذا السؤال يوضح نقصًا في المعرفة الأساسية، فالحقيقة هي أنني أفتقر إلى المعرفة الأساسية.

أريد بعض المساعدة في التعرف على كيفية إنشاء مكرر للفصل الذي قمت بإنشائه.

لدي فئة "الشكل" التي تحتوي على حاوية من النقاط.لدي فئة "قطعة" تشير إلى الشكل وتحدد موضع الشكل.القطعة لا تحتوي على شكل، فهي تشير فقط إلى شكل.

أريد أن يبدو الأمر وكأن القطعة عبارة عن حاوية من النقاط التي تشبه تلك الموجودة في الشكل الذي تشير إليه ولكن مع إضافة إزاحة موضع القطعة.

أريد أن أكون قادرًا على تكرار نقاط القطعة تمامًا كما لو كانت القطعة عبارة عن حاوية بحد ذاتها.لقد قمت بالقليل من القراءة ولم أجد أي شيء ساعدني.سأكون ممتنا جدا لأية مؤشرات.

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

المحلول

يجب عليك استخدام Boost.Iterators.يحتوي على عدد من القوالب والمفاهيم لتنفيذ مكررات ومحولات جديدة للمكررات الموجودة.لقد كتبت مقال حول هذا الموضوع بالذات;إنه موجود في مجلة ACCU لشهر ديسمبر 2008.يناقش حلاً أنيقًا (IMO) لمشكلتك بالضبط:كشف مجموعات الأعضاء من كائن ما، باستخدام Boost.Iterators.

إذا كنت ترغب في استخدام stl فقط، فإن كتاب جوسوتيس يحتوي على فصل عن تنفيذ مكررات STL الخاصة بك.

نصائح أخرى

/يحرر:أرى أن المكرر الخاص ضروري بالفعل هنا (لقد أخطأت في قراءة السؤال أولاً).ومع ذلك، أترك الكود أدناه قائمًا لأنه يمكن أن يكون مفيدًا في ظروف مماثلة.


هل المكرر الخاص ضروري بالفعل هنا؟ربما يكون كافيًا إعادة توجيه جميع التعريفات المطلوبة إلى الحاوية التي تحتوي على النقاط الفعلية:

// Your class `Piece`
class Piece {
private:
    Shape m_shape;

public:

    typedef std::vector<Point>::iterator iterator;
    typedef std::vector<Point>::const_iterator const_iterator;

    iterator begin() { return m_shape.container.begin(); }

    const_iterator begin() const { return m_shape.container.begin(); }

    iterator end() { return m_shape.container.end(); }

    const_iterator end() const { return m_shape.const_container.end(); }
}

هذا على افتراض أنك تستخدم vector داخليًا ولكن النوع يمكن تعديله بسهولة.

هنا تصميم STL مثل الحاوية المخصصة يعد مقالًا ممتازًا يشرح بعض المفاهيم الأساسية حول كيفية تصميم فئة حاوية مثل STL جنبًا إلى جنب مع فئة التكرار الخاصة بها.المكرر العكسي (أصعب قليلاً) على الرغم من تركه كتمرين :-)

هث،

يمكنك قراءة هذا مقالة دي جي

بشكل أساسي، ورث من std::iterator لإنجاز معظم العمل نيابةً عنك.

يمكن أن تكون كتابة التكرارات المخصصة في لغة C++ مطولة ومعقدة للفهم.

نظرًا لأنني لم أتمكن من العثور على طريقة بسيطة لكتابة مكرر مخصص كتبته رأس القالب هذا قد يساعد ذلك.على سبيل المثال، لجعل Piece فئة قابلة للتكرار:

#include <iostream>
#include <vector>

#include "iterator_tpl.h"

struct Point {
  int x;
  int y;
  Point() {}
  Point(int x, int y) : x(x), y(y) {}
  Point operator+(Point other) const {
    other.x += x;
    other.y += y;
    return other;
  }
};

struct Shape {
  std::vector<Point> vec;
};

struct Piece {
  Shape& shape;
  Point offset;
  Piece(Shape& shape, int x, int y) : shape(shape), offset(x,y) {}

  struct it_state {
    int pos;
    inline void next(const Piece* ref) { ++pos; }
    inline void begin(const Piece* ref) { pos = 0; }
    inline void end(const Piece* ref) { pos = ref->shape.vec.size(); }
    inline Point get(Piece* ref) { return ref->offset + ref->shape.vec[pos]; }
    inline bool cmp(const it_state& s) const { return pos != s.pos; }
  };
  SETUP_ITERATORS(Piece, Point, it_state);
};

بعد ذلك ستتمكن من استخدامها كحاوية STL عادية:

int main() {
  Shape shape;
  shape.vec.emplace_back(1,2);
  shape.vec.emplace_back(2,3);
  shape.vec.emplace_back(3,4);

  Piece piece(shape, 1, 1);

  for (Point p : piece) {
    std::cout << p.x << " " << p.y << std::endl;
    // Output:
    // 2 3
    // 3 4
    // 4 5
  }

  return 0;
}

كما يسمح بإضافة أنواع أخرى من التكرارات مثل const_iterator أو reverse_const_iterator.

اتمني ان يكون مفيدا.

الحل لمشكلتك ليس إنشاء التكرارات الخاصة بك، ولكن استخدام حاويات STL والمكررات الموجودة.قم بتخزين النقاط في كل شكل في حاوية مثل المتجه.

class Shape {
    private:
    vector <Point> points;

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

for (vector <Point>::iterator i = points.begin(); i != points.end(); ++i)
    /* ... */

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

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