向容器中插入或者返回对象,或者其他类型的操作(remove unique)都会涉及到对象的拷贝。
这也是为什么要求容器的元素类必须支持拷贝(拷贝构造函数, 拷贝复制函数)的原因。
以类Widget为例 :
class Widget
{
public:
...
Widget(const Widget&);
Widget& operator = (const Widget&);
...
};
如果大量向容器中插入元素,同时拷贝构造函数的开销又比较大,那么操作将非常耗时。
如果向一个基类对象的容器中插入子类对象,将会出现"对象剥离",插入时调用的是基类的拷贝构造函数,而不是子类的拷贝构造函数。
下面就是这种情况:
class SpecialWidget : public Widget { ... }
std::vector<Widget> datas;
SpeicalWidget one;
datas.push_back(one);
修改也很容易,只需要保存基类指针。
std::vector<Widget*> datas;
SpecialWidget one;
datas.push_back(&one);
容器存在的意义是为了避免不必要的拷贝,但是无法避免拷贝。
vector可以在需要时才创建对象,这点数组无法做到的。
class Widget { ... };
Widget data1[10];
std::vector<Widget> data2;
data2.reverse(10);
data1使用默认构造函数创建了10个Widget对象,不管其中是否全部都要使用。
data2只是预留了10个对象的空间,而没有立即创建10Widget对象。