博览网 c++课程 第二周课程笔记
课程地址
1/16/2017 11:23:33 PM
带指针(变量)的类设计
拷贝构造函数、拷贝函数和析构函数
- 三大函数。带指针的类设计一定要重视这三大函数,主要是涉及到危险的指针赋值操作。
堆和栈
- 栈对象(变量)在离开作用域时销毁,调用对象的析构函数。
- 静态栈对象,离开作用于还存在,在整个程序结束的时候析构。
- 全局对象的生命周期,比main函数早存在,在整个生命周期结束之后才结束。
- 堆对象(变量)控制权交给程序员,自己创建(new),自己负责销毁(delete),所以一定要注意指针的赋值(拷贝)操作,容易产生问题,在学习c++11的智能指针后尽可能多使用智能指针。
- 堆对象的生成,使用new,先分配堆空间,再调用构造函数。
new的动作分解:首先分配足够的内存空间,然后将内存进行转型操作,然后调用对象的构造函数
void* mem = operator new(sizeof(class));
pc = static_cast<class*>(mem);
pc->class::class(*);
- 堆对象的释放,使用delete,先调用析构函数,然后再释放堆内存。
class::~class(pointer); operatr delete(pointer)
- 在String的设计中,在析构函数中调用delete释放字符串。
- 候老师的重点内容,在new复数类(上一课例子),在调试模式下会多得到32个字节,中间是类的大小(两个double),后面还有四个字节,加上一头一尾的小cookie中,一共是8+(32+4)+(4+4)=52个,在vc下分配内存是16的倍数,为64个。为什么?在回收的时候顺利的回收。在relese模式下没有头尾的添加,但是有cookie,8+(4+4)=16。注意小cookie中的地址记录大小和最后一个位比特来表示是借出还是回收。字符串类(String,成员变量只有一个char指针,4比特),在调试模式下4+(32+4)+(4+4)=48,在relese模式下位4+(4+4)=12,变成16的倍数是16。
- 如果分配的是数组:array new对应array delete。
class *p = new class[3];
(8X3)+(32+4)+(4X2)+4,最后的加4是VC的做法,用一个整数来记录数组的长度,结果是72,调整到16的倍数为80,其余的模式以此类推。正确的搭配模式下调用array delete时,看到cookie,知道要删除的空间的大小,不会引起内存泄漏,但是会根据记录数组的区域,3次调用析构函数。如果array new不用array delete的话,只会调用一次析构函数,这样剩下的指针所指对象不会调用析构函数。感悟:透彻明了!
字符串String类的实现细节。
- 头文件中添加防卫式定义。
- 字符串里面的类属性,放数组不好因为事先不知道大小,一般放一个指针,大小根据放的内容动态分配;32位平台上一个指针4个byte。
- big three 函数:拷贝构造函数(优先考虑传入引用,不修改变量的值,所以添加const),拷贝复制函数作为成员函数,在返回时传出引用。析构函数,释放开辟的堆内存。
- 注意String的获取成员变量m_data指针,返回const修辞的char指针。
- 拷贝赋值函数注意首先判断是否是自我赋值。
if(this==&str)return *this;
类模板函数模板
静态static
- 类里面的可以包含static函数和static成员变量
- 每个类对象包含各自的成员变量,一个成员函数要被多个对象调用,需要this指针。
- 对象中静态static成员不变量属于类,只存在一份。(多个对象共用)
- 类的静态函数没有this指针,所以不能访问对象里面的类成员,只能是处理静态数据。
- 静态类成员数据,一定要在类的外面设初值或者叫定义。 注意定义方法
type class::member = ...
- 调用static函数的方式有两种,一是通过对象调用,第二种是通过类来调用。
模板技术
template<typename T> class name{};
- 编译器会根据不同的参数,生成不同的代码,所以使用类模板可能造成代码的膨胀。
- 了解模板函数的意义和作用处理。
- c++中的算法大量使用模板。
命名空间
- 为避免命名冲突,使用命名空间。(比较简单)
- 命名空间可以分多段定义。
- using namespace *;全开
- using ::;指定打开