STL中的容器、迭代器、算法都是模板,因此可以操作任何型别。不论是STL预先定义好的或用户自行定义的都可以。然而,由于某些加诸于元素身上的操作行为,某些需求条件也就相应出现了。STL容器元素必须满足以下三个基本条件:
- 必须可通过拷贝复制构造函数进行复制。副本与原本必须相等,亦即所有相等测试的结果必须显示原本和副本行为一致。 所有容器都会在内部生成一个元素副本,并返回该暂时性副本,因此拷贝构造函数会被频繁地调用。所以拷贝构造函数的性能应该尽可能地优化,虽然这不是必须的条件之一,但可视为获得良好性能的诀窍。如果对象的拷贝需要耗费大量的时间,你可以选用基于引用计数的智能指针来使用容器,从而避免拷贝对象带来的性能开销。
- 必须可以通过operator = 赋值操作符来完成赋值动作。容器和算法都会使用operator = 才能以新元素改写或取代旧元素。
- 必须可以透过析构函数完成动作的销毁。当容器元素被移除,容器内的副本将被销毁,因此析构函数绝对不能设计为private。此外,依C++惯例,析构函数绝对不能抛出异常。
这三个条件对任何class而言其实都是隐式成立的。如果某个class既没有为上述动作定义特殊版本,也没定义任何“可能破坏这些动作之健全性的”特殊成员,那么它自然而然也就满足了上述条件。下面几个条件也得满足:
- 对序列式容器而言,元素的defaut构造函数必须可用。 我们可以在没有给予任何初值的情况下,创建一个非空容器,或增加容器的元素个数,这些元素都将以default构造函数完成。
- 对于某些动作,必须定义operator = = 以执行相等测试。如果你有搜寻需求,这一点很重要。
- 在关联式容器中,元素必须定义出排序准则。缺省情况下 operator<, 透过仿函数less<>调用。
#include<vector>
using std::vector;
class dansir
{
public:
dansir() = delete;
dansir(const dansir&) = delete;
dansir& operator = (const dansir&) = delete;
};
int main(int argc, char *argv[])
{
vector<dansir> vtDir; // 此处会报错,因为默认构造函数被删除了,不存在默认构造函数
vector<dansir> vtDir1;
vtDir = vtDir1; // 此处会报错,因为赋值函数被删除了,不存在赋值函数
return 0;
}
#include<vector>
using std::vector;
class dansir
{
public:
dansir() {};
~dansir() = delete;
};
int main(int argc, char *argv[])
{
vector<dansir> vtDir;
dansir s;
vtDir.push_back(s);
vtDir.erase(vtDir.begin()); // 此处会报错,因为erase会调用dansir的析构函数,而析构函数被删除了
return 0;
}