我正在尝试实现一个模板,该模板允许创建一个派生自vector<>的类。这样在删除时,矢量的元素被删除。以下代码段表示尝试这样做:
include <vector>
using namespace std;
template <class P>
class TidyVector : public vector<P> {
public:
~TidyVector() {
while (vector<P>::size()) {
P pi = vector<P>::back();
vector<P>::pop_back();
delete pi;
}
}
}
TidyVector<int*> i;
尝试使用g ++ -c try.cc编译它会导致以下错误消息:
try.cc:1: error: expected constructor, destructor, or type conversion before '<' token
try.cc:6: error: expected template-name before '<' token
try.cc:6: error: expected `{' before '<' token
try.cc:6: error: expected unqualified-id before '<' token
try.cc:17: error: aggregate 'TidyVector<int*> i' has incomplete type and cannot be defined
发生了什么 - 为什么这不起作用?或者,或许,一个更合适的问题:处理这种情况的标准方法是什么(删除时自动清理矢量)?
答案 0 :(得分:4)
我认为应该是#include&lt;矢量&gt;。这就是一个错误。
其次,你应该避免从vector继承,它没有虚拟析构函数,所以你的类可以很容易地转换为标准向量而你的析构函数不会运行。
(哦,你把半结肠从课堂上移开了)
第三,你考虑过做矢量&lt;升压:: shared_ptr的&LT; some_class&gt; &GT;代替?
澄清为什么shared_ptr方法更好:你的班级现在只在一个实例中清理东西;如果课程被破坏,他们还在那里。但是说你有一个带有10个元素的TidyVector foo然后有人会这样做:
foo[5] = new int; // Memory leak!
或者
foo.resize(0); // Memory leak!
或者
foo.erase(foo.begin()); // Memory leak!
列表继续
答案 1 :(得分:4)
已经有一个类可以执行此操作:Boost's ptr_vector。我建议检查一下,然后看看他们是如何做到的。简短的回答:他们不使用继承,他们使用组合。
答案 2 :(得分:1)
阅读编译器错误消息:对于初学者来说,你错过了来自#include的'#'。
在析构函数中,您不需要指定vector<P>::
- 您是从向量派生的,因此无需限定即可调用其方法,例如size()等。
向量将清理自己的存储空间,因此您无需在其上调用pop_back()。尝试
for (iterator i = begin(); i != end; ++i)
delete *i;
不要手动执行此操作,而是在向量中保持智能指针(如shared_ptr),然后为您删除元素,而不需要派生类。
关于是否从标准库容器中获取是一个好主意,有不同的意见,这里的搜索将指向您对该问题的几个讨论。