문제

이상한 문제에 직면했습니다.나는 Parent 추상 클래스(순수 가상 test() 메소드 구현)와 Child 클래스(test() 메소드 구현)를 작성했습니다.

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

        virtual bool test() const = 0;
};

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

그런 다음 부모에 대한 포인터의 2차원 배열을 포함하는 "Grid" 클래스를 작성했습니다.배열은 벡터 라이브러리를 사용하여 수행됩니다."_cells"는 부모에 대한 포인터의 너비*높이 벡터입니다._cells는 동적 할당을 사용하여 Grid 개체를 생성하는 동안 채워지고 소멸자에서 해제됩니다.Operator() (int a, int b)는 다음 패턴을 사용하여 Parent 객체를 호출할 수 있도록 오버로드됩니다.마이그리드(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를 파괴하고 g에서 새로운 4x4 그리드를 구성해야 합니다.그러나 완전히 실패합니다.

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