你应该使用std::list
. 实际上,您应该使用std::vector
,因为对于大多数实际目的来说它更快(列表只有在对象非常大或构建起来非常昂贵时才会更快)并且您不需要随机访问。
new T(*(cctorList->info));
不会编译,因为cctorList
( list&
) 没有operator->
并且它也没有info
成员。
复制构造函数最好根据其他更原始的操作(如push_back
迭代)来实现。所以首先做这些,然后复制构造函数变成:
template <class T>
list<T>::list(const list &cctorList)
{
std::copy(begin(cctorList), end(cctorList), std::back_inserter(this));
}
事实上,我只是模板该构造函数:
template <class T, class Collection> list(const Collection &cctorList)
(身体保持不变)。它用作复制构造函数,但也允许从任何其他可以隐式转换为 T 的任何类型的集合进行复制。
实际数据应按值保存。即node
应该定义为
struct node
{
node *next;
node *previous;
T info;
}
无论如何,您都在复制该值,因此您无需针对何时进行两次单独的分配node
以及T
何时进行分配。
编辑:你说你想学习概念。但现代 C++ 最重要的概念是算法的组合。他们的定义通常是微不足道的。的基本实现std::copy
只是:
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator begin, InputIterator end, OutputIterator out) {
for(;begin != end; ++out, ++begin) *out = *begin;
}
现在这似乎没有分配任何东西。诀窍在于back_insertion_iterator
. 插入迭代器是一种无需预先分配序列即可使其工作的技巧。它在基础集合上定义operator*
using并忽略。这满足了“输出迭代器”的概念,因为它只保证在这两个调用严格交错时工作,并使算法可以处理从普通旧数组到输出流的许多事情。push_back
operator++
另一部分是虽然琐碎的定义是正确的,但它们不是库中使用的实际定义。库中的实际定义进行了优化。例如,通常std::copy
会检查输入迭代器是否知道它们的距离,以及输出是否是插入操作符以对操作进行排序reserve
并调用它以避免某些分配。这些是优化,取决于标准库的实现细节。
如果您想了解它们,您可以从标准库中写下事物的基本实现并测试它们的工作方式。std::copy
但是您应该遵循标准库定义事物的方式,通过简单的辅助位(如、std::swap
、插入迭代器适配器等)构建它们。如果你查看标准库,大多数函数都是单行的!
Edit2:尽管标准库提供了所有通用性,但仍然有人批评它不够通用。例如GotW #84: Monoliths “Unstrung”讨论了哪些方法std::string
可以转换为通用算法。