0

对于我的一个程序,我做了一个小函数来清除我拥有的各种 std::vectors 指针。

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

    a.clear();
}

我在这里一定做错了什么,因为在像这样的析构函数中调用这个函数时:

clearPtrVector(neurons,neurons.size());

我两次得到以下未定义的引用:

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

我不得不承认我不熟悉 std::allocator 是什么,所以我猜不出问题可能出在哪里。非常感谢任何帮助。提前致谢!

-左撇子

4

6 回答 6

8

热修复

请改写以下内容:

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

    a.clear();
  }

确保在每次使用模板之前在编译器可以看到的地方定义模板。如果你不创建声明,你应该是安全的,否则你应该得到一个编译错误。如果您出于任何原因确实创建了声明,请务必根据需要在任何地方包含定义。

重新设计

也就是说,我认为正确的解决方案是重新考虑您的设计并使用能够正确处理破坏的容器,这样您就不必手动进行操作,这很乏味,而且如果您需要,几乎不可能正确完成异常安全。使用std::shared_ptr而不是原始指针,或std::auto_ptr使用能够容纳它们的容器(std::vector不能存储auto_ptr值)。一种可能的解决方案是使用Boost Pointer Container

于 2009-05-27T07:54:40.437 回答
3

您的 clearPtrVector 实现是否在头文件中?因为如果它在单独的 .cpp 文件中,链接器将找不到它。

于 2009-05-27T08:04:46.797 回答
3

一些东西:

在您的原始代码中,不要传递大小;只需从向量中获取它:

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

    a.clear();
}

其次,只需传入向量本身,而不是它指向的类型:

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

    vec.clear();
}

第三,该错误听起来像是您将其放置在 .cpp 文件中。代码会在你第一次调用函数时生成,这意味着编译器需要知道函数的定义。将函数移动到头文件中,以便编译器可以找到它。

最后,考虑使用更适合此的东西:

于 2009-05-27T08:11:00.437 回答
2

确保您在头文件(.h、*.hpp)中有此函数,因为如果您在源文件中定义它并在头文件中使用原型,您将收到未定义的引用链接器错误。

未定义的引用错误意味着编译器已找到函数的引用,但链接器未能在目标文件中找到该函数的引用。任何模板函数都必须在头文件中定义,以便编译器能够将其放入任何使用该函数的源文件中。

于 2009-05-27T08:09:12.203 回答
0

正如我在回答您的第一个问题https://stackoverflow.com/questions/891913?sort=newest时提供的,一个答案如下:

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

适用于所有容器类型。请注意,未提供 size 参数,而是从集合中获取的 - 这是设计此类函数的正确方法,将 size 作为单独的值提供只会导致灾难。

于 2009-05-27T08:29:37.917 回答
0

重新设计不是 清理-一个-stl-list-vector-of-pointers的副本吗

评论

如果您不使用其中一个智能指针,请使用boost::checked_delete函数而不是 delete 以确保您没有删除不完整的类型。

于 2009-05-27T08:12:04.333 回答