Vetor de função ponteiros modelo de compensação falha ao compilar com a mensagem “referência indefinida”

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

  •  06-09-2019
  •  | 
  •  

Pergunta

Para um programa da mina eu fiz uma pequena função para limpar os vários std :: vetores de ponteiros que eu tenho.

template <class S>
void clearPtrVector(std::vector<S*> &a,int size)
{
    for(size_t i = 0; i < size; i++)
         delete a[i];

    a.clear();
}

Eu devo ter feito algo errado aqui embora desde quando chamar essa função em um destruidor assim:

clearPtrVector(neurons,neurons.size());

Eu recebo a seguinte referência indefinida duas vezes:

undefined reference to `void clearPtrVector<Neuron>(std::vector<Neuron*,std::allocator<Neuron*> >&, int)'

Eu tenho que admitir que eu não estou familiarizado com o que o std :: allocator é, então eu não posso adivinhar o que o problema pode estar aqui. Qualquer ajuda é muito apreciada. Agradecemos antecipadamente!

-Lefteris

Foi útil?

Solução

Hot Fix

Write seguinte em vez disso:

  template <class Vector>
  void clearPtrVector(Vector &a)
  {
    for(size_t i = 0; i < a.size(); i++)
         delete a[i];

    a.clear();
  }

Certifique-se de definir a algum lugar modelo onde compilador pode vê-lo antes de cada utilização do modelo. Se você não criar uma declaração, você deve ser seguro, caso contrário, você deve obter um erro de compilação. Se você criar uma declaração por qualquer razão, ser o dobro cuidado para incluir definição em todos os lugares, conforme necessário.

Redesign

Dito isso, eu acho que a solução adequada seria a repensar seu projeto e usar um recipiente que irá lidar com a destruição adequadamente, de modo que você não tem que fazê-lo manualmente, o que é tedioso, e quase impossível de se fazer corretamente se você precisa de segurança exceção. Use std::shared_ptr em vez de ponteiros crus, ou std::auto_ptr com um recipiente que é capaz de mantê-los (std::vector não pode armazenar valores auto_ptr). Uma possível solução seria usar impulsionar Pointer Container

Outras dicas

É sua implementação clearPtrVector em um arquivo de cabeçalho? Porque se for em um arquivo .cpp separado, o vinculador não vai encontrá-lo.

Algumas coisas:

Em seu código original, não passam no tamanho; apenas obtê-lo a partir do vetor:

template <class S>
void clearPtrVector(std::vector<S*> &a)
{
    for(size_t i = 0; i < a.size(); ++i)
    {
         delete a[i];
    }

    a.clear();
}

Em segundo lugar, apenas passe no próprio vector, não o tipo que ele aponta para:

template <class Vector>
void clearPtrVector(Vector &vec)
{
    for(size_t i = 0; i < vec.size(); ++i)
    {
         delete vec[i];
    }

    vec.clear();
}

Em terceiro lugar, que os sons de erro como você tê-lo colocado em um arquivo .cpp. O código será gerado quando você chamar a função, o que significa que as necessidades do compilador saber a definição da função. Mova a função no arquivo de cabeçalho, para que o compilador pode encontrá-lo.

Por fim, considere usar as coisas mais adequadas a esta:

Certifique-se de que você tem essa função em um arquivo de cabeçalho (.h, * .hpp) porque se você definiu em um arquivo de origem com um protótipo em um arquivo de cabeçalho você tem um erro de vinculador referência indefinida.

Undefined meios de erro de referência que compilador encontrou a referência da função, mas vinculador não conseguiu encontrar uma referência de que a função entre os arquivos objeto. Qualquer função de modelo tem que ser definido em um arquivo de cabeçalho para que o compilador será capaz de colocá-lo em qualquer arquivo de origem que faz uso da função.

Não é o redesenho uma duplicata limpeza-up-an-STL-list-vector-de-ponteiros

Nota

Se você não usar um dos ponteiros inteligentes, uso boost :: função checked_delete em vez de exclusão para se certificar de que você não está apagando um tipo incompleto.

Como eu fornecido na minha resposta à sua primeira pergunta https://stackoverflow.com/questions/891913?sort=newest , uma resposta é a seguinte:

template <class C> void FreeClear( C & cntr ) {
    for ( typename C::iterator it = cntr.begin(); 
              it != cntr.end(); ++it ) {
        delete * it;
    }
    cntr.clear();
}

que funciona para todos os tipos de contêineres. Observe que o parâmetro de tamanho não é fornecido, mas é obrtained da coleção -. Esta é a maneira correta de projetar tais funções, proporcionando o tamanho como um valor separado só pode levar ao desastre

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