1. C++三法则:如果需要析构函数,则一定需要拷贝构造函数和赋值操作符
如何理解这句话,首先,从“如果需要析构函数”这里我们知道,类中必然出现了指针类型的成员(否则不需要我们写析构函数,默认的析构函数就可以用了),所以,我们需要自己写析构函数来释放给指针所分配的内存来防止内存泄露,那么为什么说“一定需要拷贝构造函数和赋值操作符”呢,原因还是这样:类中出现了指针类型的成员。有指针类型的成员,我们必须防止浅拷贝问题,所以,一定需要拷贝构造函数和赋值操作符,这两个函数是防止浅拷贝问题所必须的
2. 往vector容器里push_back()一个元素,拷贝构造几次
这个最好还是看源码实现,简单来说,先开辟一组新的空间,放旧元素,再添加新元素进去,最后释放旧空间。不过标准库又有新做法,就是当需要获取新的空间时,开辟比所需要的空间更大,来预留空间为备用
3. 虚析构问题
先看上面3种情况,其实设不设为虚函数都没问题, 就是怕delete一个动态分配的对象,且动态类型为子类的时候,会出现指针的静态类型与被删除对象的动态类型不符合的情况。
为什么要让父类的析构函数要设成虚的, 主要有一下方面
- 对象都是通过this指针来找到其对应的成员变量, 成员函数
- 如果子类有重写父类的方法, 就从本类去寻找, 实在没有就去父类去找,
- 设为虚肯定就有了虚函数表, 父类虚, 子类也虚, 那么delete 父类指针, 就会去当前绑定的子类对象的虚函数表调用其析构函数, 然后编译器会在其子类的析构加上父类的析构函数从而达到彻底清除的目的
不管怎么说, 你new一个对象, this指针会调整到这个类似所管辖的区域,然后去虚函数表找到该析构函数的地址(这个表是固定的,也就是函数地址是确定的), 然后如果有this指针调整的话, 会有一个thunk代码块(其目的就是为了移动到子类的析构函数), 最后调用子类析构,回收内存的目的
\