对于我的程序,我做了一个小函数来清除我所拥有的各种std ::指针向量。
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是什么,所以我无法猜出这里可能出现的问题。任何帮助都非常感谢。提前谢谢!
-Lefteris
答案 0 :(得分: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
答案 1 :(得分:3)
您的clearPtrVector实现是否在头文件中?因为如果它位于单独的.cpp文件中,链接器将无法找到它。
答案 2 :(得分: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文件中。首次调用函数时将生成代码,这意味着编译器需要知道函数的定义。将函数移动到头文件中,以便编译器可以找到它。
最后,考虑使用更适合的内容:
答案 3 :(得分:2)
确保在头文件(.h,* .hpp)中具有此功能,因为如果您在头文件中使用原型在源文件中定义它,则会出现未定义的引用链接器错误。
未定义的引用错误意味着编译器已找到该函数的引用,但链接器未能在目标文件中找到该函数的引用。必须在头文件中定义任何模板函数,以便编译器能够将它放在任何使用该函数的源文件中。
答案 4 :(得分:0)
重新设计不是重复的 cleaning-up-an-stl-list-vector-of-pointers
<强>备注强>
如果您不使用其中一个智能指针,请使用boost::checked_delete功能而不是删除功能,以确保您没有删除不完整的类型。
答案 5 :(得分: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参数未提供,但是从集合中获取 - 这是设计此类函数的正确方法,将大小视为单独的值只会导致灾难。