تخزين كائنات غير متجانسة في ناقلات مع الكائنات المخصصة كومة

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

سؤال

وتخزين الكائنات في ناقلات غير متجانسة مع الكائنات المخصصة كومة

ومرحبا،

ويقول لدي CA فئة مجردة، والمستمدة في CA1، CA2، وربما آخرين.

وأريد أن أضع الأشياء من هذه الأنواع المشتقة في ناقلات، وأنني embbed إلى CB الصف. للحصول على تعدد الأشكال الحق، ولست بحاجة لتخزين متجه من المؤشرات:

class CB
{
    std::vector <CA*> v;
};

والآن، ويقول لدي وظيفة الرئيسية التالية:

int main()
{
    CB b;
    CA1 a1;
    CA2 a2;
    b.Store( a1 );
    b.Store( a2 );
}

وكيف يمكنني كتابة void CB::Store(const CA&) الأسلوب في طريقة بسيطة، وبالتالي فإن الكائنات المخزنة البقاء على قيد الحياة عندما يحصل على تدمير الكائنات الأصلية (التي لا تحدث في مثال بسيط أعلاه).

ومشكلتي هي أنني بحاجة إلى كائنات النسخة الأولى على كومة قبل نسخ عنوان في ناقلات، ولكن كيف يمكنني إنشاء كائن من نوع مشتق؟ من المؤكد أن أتمكن من استخدام RTTI، والبحث عن جميع أنواع ممكن، وإنشاء وتخصيص المؤشر، ونسخ (مع الصب السليم) الكائن في المساحة المخصصة قبل الدفع به في ناقلات. ولكن هذا يبدو معقدا جدا، أليس كذلك؟

هل هناك طريقة أسهل؟

(ودون استخدام التخصيص الحيوي بشكل رئيسي!)

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

المحلول

وعادة، سوف توفر وظيفة استنساخ:

struct CA
{
    virtual CA *clone(void) const = 0;
    virtual ~CA() {} // And so on for base classes.
}

struct CA1 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA1(*this);
    }
}

struct CA2 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA2(*this);
    }
}

وهذا ما يسمى الظاهري منشئ ، يمكنك بناء على نسخ من الأشياء في وقت التشغيل:

void CB::Store(const CA& pObject)
{
    CA *cloned = pObject.clone();
}

ويجب عليك أن تنظر باستخدام Boost.Pointer الحاويات مكتبة . أن الشفرة هي:

boost::ptr_vector<CA> objects;

void CB::Store(const CA& pObject)
{
    objects.push_back(pObject->clone());
}

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

نصائح أخرى

ويبدو وكأنه كنت في حاجة الى وظيفة استنساخ () في فئة مجردة بك أن الفصول الدراسية المستمدة ستنفذ.

class CA
{
   public:
   virtual ~CA() {}
   virtual CA* clone() const = 0;
}

class CA1 : public CA
{ 
    public:
    virtual CA *clone() const
    {
       return new CA1(*this);
    }
};

وهناك احتمال أن يكون لtemplatize مخزن على نوع حجتها:

class CB
{
public:
    template<class T>
    void Store(const T& t)
    {
         v.push_back(new T(t));
    }

private:
    std::vector <CA*> v;
};

وعلى الرغم من تحذير: على عكس "استنساخ ()" حل نشرت من قبل الآخرين، وهذا هو عرضة للتشريح. على سبيل المثال، وهذا يعمل بشكل جيد:

CB b;
CA1 a1;
CA2 a2;
b.Store(a1);
b.Store(a2);

ولكن هذا لا:

CA1 a1;
CA* a = &a1;
b.Store(*a); //Ouch! this creates a new CA, not a CA1

وإعطاء نسخة المنشئ المحمية لCA يمنع هذا سوء الاستخدام. ومع ذلك، إذا علينا مواصلة فرعية CA1، فإن القضية تعود.

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