Pergunta

Eu estou enfrentando um estranho problema.Eu escrevi um Pai de classe abstrata (a implementação de um puro virtual de teste() método) e seu Filho (classe de implementação do teste() método).

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

        virtual bool test() const = 0;
};

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

Então, eu escrevi uma "Grade" de classe que deve conter uma matriz de duas dimensões de ponteiros para os Pais.A matriz é feito usando o vetor de biblioteca :"_cells" é uma largura*altura vetor de ponteiros para os Pais._cells é preenchido durante o Grid de construção de objeto usando alocação dinâmica e liberado no processo de destruição.Operador() (int a, int b) está sobrecarregado, a fim de ser capaz de chamar o Pai de objeto usando este padrão :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();
};

Na minha função principal, g é uma primeira grelha 2x2 criados na pilha.Em seguida, ele deve destruir g e para a construção de uma nova grade de 4x4 em g.Mas é completamente falha :

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

Eu acho que o problema vem de alocação dinâmica/desallocation de cada célula, mas eu não encontrei uma maneira de resolvê-lo.

Aqui está todo o meu código, eu não simplificaram-lo mais.Eu fiz o meu melhor.Desculpe.

#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;
}

Obrigado.

Foi útil?

Solução

O Grid classe não tem uma cópia operador de atribuição, para os compiladores padrão gerado versão será usada em vez disso.É muito simples, e não apenas uma cópia superficial dos membros.O que significa que os ponteiros criados para o temporário objeto Grid(4, 4) são copiados (apenas os ponteiros, e não o que eles apontam para), e quando o objeto temporário é destruído, assim como os ponteiros (o destruidor para o objeto temporário).Isso deixa você com um objeto g com ponteiros para agora excluídos da memória.

Eu sugiro que você leia sobre a regra de três.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top