读完C++对象模型书后,做一个笔记整理
第一章-关于对象
第二章-构造函数语义学
第三章-Data语义学
第四章-Function语义学
第五章-构造拷贝解析语义学
第六章-执行期语义学
第七章-在对象模型的尖端
对象的构造和析构
- 一般我们尽量把obj放在使用它的地方附近,以节省不必要的对象产生和销毁。
- 全局对象,最好不要用需要静态初始化的全局变量。其需要编译器处理何时构造何时析构,实现并不统一。
- 局部静态对象,目前要求其在需要时才创造出来,至于何时销毁,编译器需要自行维护所有静态对象的一个执行期链表。
- 对象数组,若无构造析构,则仅分配内存,否则编译器会用构造和析构每个元素。
new 和delete
- new 先分配内存,再初始化
- delete不会对指针值为0的情况做任何操作,delete 0是可以的。但delete不会将指针重置为0,而delete后,其它地方若还用此指针结果未定义
- 一般情况销毁对象用delete即可,而delete[] ptr这种形式只在数组时才用。编译器只在delete加上[]时才会寻找数组长度。
Base* p = new Derived[10];
// Derived* p = new Derived[10]; // 应该用子类指针保存数组返回指针
delete[] p; // delete按指针类型来析构 p类型为Base,析构会不正确。
- placement new
// 直接返回地址并调用构造函数在地址上,placement new的功能。
void* operator new(size_t, void* p)
{
// 编辑器会自动扩充下面这句
// Point2w* ptw=(Point2w*)p; if (ptw!=0) ptw->Point2w::Point2w();
return p;
}
char* pmem = new char[size_of(Point2w)];
Point2w* tmp = new(pmem) Point2w;
tmp.~Point2w();
Point2w* tmp2 = new(tmp) Point2w;
- 在同一内存地址上,必须是同一类型对象,若不同结果未定义。
临时性对象
- 临时对象产生在有必要或较方便时,由编译器来定义临时对象
- 临时对象的销毁,应为引起临时对象产生的表达式求值过程的最后一步
- 凡含有表达式结果的临时对象,应在obj初始化完成后再销毁
- 如果临时对象绑定了引用,对象保留到引用结束或临时对象的生存区间结束
下一篇 第七章-在对象模型的尖端