سؤال

أواجه مشكلة غريبة.لقد كتبت فئة ملخصة الأصل (تنفيذ طريقة اختبار افتراضية خالصة) وفئتها الفرعية (تنفيذ طريقة الاختبار ()).

class Parent
{
    public :
        Parent();
        virtual ~Parent() = default;

        virtual bool test() const = 0;
};

class Child : public Parent
{
    public :
        bool test() const;
};

بعد ذلك، كتبت فئة "الشبكة" التي من المفترض أن تحتوي على مجموعة ثنائية الأبعاد من المؤشرات إلى الأصل.يتم تنفيذ المصفوفة باستخدام مكتبة المتجهات:"_cells" هو متجه العرض*الارتفاع للمؤشرات إلى الأصل._يتم ملء الخلايا أثناء إنشاء كائن الشبكة باستخدام التخصيص الديناميكي وتحريرها في أداة التدمير.تم تحميل المشغل () (int a، int b) بشكل زائد حتى يتمكن من استدعاء الكائن الأصلي باستخدام هذا النمط:myGrid(x,y).

class Grid
{
        int _w, _h;
        std::vector<Parent*> _cells;

    public :
        Grid(int w = 0, int h = 0);
        ~Grid();
        Parent* &operator()(int x, int y);

    private :
        void generate();
};

في وظيفتي الرئيسية، g هي أول شبكة 2x2 تم إنشاؤها على المكدس.بعد ذلك، من المفترض تدمير g وبناء شبكة 4x4 جديدة في g.لكنه يفشل تماما:

Grid g(2, 2);
std::cout << g(1,1)->test() << std::endl; // Works perfectly
g = Grid(4, 4); // Probably wrong, but don't throw an exception
std::cout << g(1,1)->test() << std::endl; // SIGSEGV

أعتقد أن المشكلة تأتي من التخصيص/إلغاء التخصيص الديناميكي لكل خلية، لكنني لم أجد طريقة لحلها.

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

#include <iostream>
#include <cstdlib>
#include <vector>

class Parent
{
    public :
        Parent();
        virtual ~Parent() = default;

        virtual bool test() const = 0;
};

Parent::Parent()
{}

class Child : public Parent
{

    public :
        bool test() const;
};

bool Child::test() const
{
    return true;
}

class Grid
{
        int _w, _h;
        std::vector<Parent*> _cells;

    public :
        Grid(int w = 0, int h = 0);
        ~Grid();
        Parent* &operator()(int x, int y);

    private :
        void generate();
};

Grid::Grid(int w, int h) : _w(w), _h(h), _cells(w*h)
{
    generate();
}

Grid::~Grid()
{
    for (auto cell : _cells)
        delete cell;
}

Parent* &Grid::operator()(int x, int y)
{
    return _cells[x*_w+y];
}

void Grid::generate()
{
    int cell_num;
    for (cell_num = 0; cell_num < static_cast<int>(_cells.size()); cell_num++)
        _cells[cell_num] = new Child();
}

int main()
{
    Grid g(2, 2);
    std::cout << g(1,1)->test() << std::endl;
    g = Grid(4, 4);
    std::cout << g(1,1)->test() << std::endl;

    return 0;
}

شكرًا.

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

المحلول

ال Grid لا تحتوي الفئة على عامل تشغيل لتعيين النسخ، لذلك سيتم استخدام الإصدار الافتراضي الذي تم إنشاؤه بواسطة المترجمين بدلاً من ذلك.إنه أمر بسيط للغاية، ولا يقوم إلا بعمل نسخة سطحية من الأعضاء.وهذا يعني أن المؤشرات التي تم إنشاؤها لـ مؤقت هدف Grid(4, 4) يتم نسخها (فقط المؤشرات، وليس ما تشير إليه)، وعندما يتم تدمير الكائن المؤقت، يتم أيضًا نسخ المؤشرات (في أداة التدمير للكائن المؤقت).هذا يتركك مع كائن g مع مؤشرات إلى الذاكرة المحذوفة الآن.

أقترح عليك أن تقرأ عنها قاعدة الثلاثة.

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