容器 (Containers) 用来存储对象 (Objects), 但是被存储的对象却并非原原本本是你给他的那一个, 而是你指定对象的一个拷贝。而后续对该容器内存储对象的操作,大多也是基于拷贝的。 拷贝操作通过类的成员函数 copy constructor 或者 copy assignment constructor 来完成( 如果用户 没有自己声明这两个函数,编译器会自动生成他们):

class Widget {
public:
Widget(const Widget&); // copy constructor
Widget& operator=(const Widget&); // copy assignment operator
// Other functions.
};

如果拷贝构造函数以及拷贝赋值函数的调用开销过于昂贵,将其置于容器中,不断的拷贝有可能会成为程 序的瓶颈。

此外,考虑到类的继承,尝试将子类的对象push 到父类的 Container 中,会引起 “切片 ”问题:

vector<Widget> vw;
class SpecialWidget: public Widget {...}; // SpecialWidget inherits from // Widget above
SpecialWidget sw;
vw.push_back(sw); // sw is copied as a base class object into vw. Its specialness is lost
// during the copying

上面的例子中,将 sw push_back 到 vw 中时,被调用的 Copy Constructer 是父类 Widget 的,而非 SpecialWidget 的,这样最后存在 vw 中的对象已经不包含任何的 sw 信息,任何尝试调用 vw 特有的方 法都将失效。。。

对此的一个简单 fix 是:别在 Container 中保存对象,转而保存对象的指针,尤其是 shared pointer。

理解 STL 的 Copy。

05-17 06:53