سؤال

الرمز التالي ، يطبع

Derived
Base
Base

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

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}
};

class Derived: public Base{
public:
  void print(){ cout << "Derived" << endl;}
};

class User{
public:
  vector<Base> items;
  void add_item( Base& item ){
    item.print();
    items.push_back( item );
    items.back().print();
  }
};

void fill_items( User& u ){
  Derived d;
  u.add_item( d );
}

int main(){
  User u;
  fill_items( u );
  u.items[0].print();
}
هل كانت مفيدة؟

المحلول

تحتاج إلى استخدام المؤشرات ، وتحتاج إلى إعطاء المدمرة الافتراضية من الفئة A الأساسية. لا يتعين على المدمر القيام بأي شيء ، ولكن يجب أن يكون موجودًا. وظيفة الإضافة الخاصة بك ثم تبدو مثل:

void add_item( Base * item ){
    item->print();
    items.push_back( item );
}

حيث العناصر vector<Base *>. لتدمير العناصر (على افتراض مدمرة افتراضية):

for( int i = 0; i < items.size(); i++ ) {
    delete items[i];
}
items.clear();

نصائح أخرى

تحتاج إلى مدمرة افتراضية لقاعدة للتأكد من كائنات النوع Derived يتم تدميرها بشكل صحيح عند الاتصال بحذف على مؤشر من النوع Base.

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}

  virtual ~Base( ) { }  // virtual destructor
};

ثم يمكنك استخدام التعزيزات PTR_VECTOR لتخزين المؤشرات على الأشياء التي يتم حذفها عند تدمير الحاوية.

فقط شرح:

من أجل فهم ما يجري ، قد تحاول تحديد ملخص قاعدة الفصل (على سبيل المثال تحديد أي طريقة Pure Virtual). في هذه الحالة ، أتوقع أن ترى أخطاء البرمجيات. وبهذه الطريقة ، ستتعرف على ما يفعله المتجه فعليًا: إنه ينشئ مثيلات جديدة من قاعدة الفصل عن طريق إنشاء نسخ عند push_back (مشتقة). هذا هو السبب في أنك تريد استخدام المؤشرات بدلاً من ذلك. ثم يعمل Vector مع كائناتك التي تم إنشاؤها في الأصل من النوع المشتق بدلاً من نسخ خاصة من قاعدة النوع.

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