文档介绍:《C++编程思想》阅读笔记
动态对象创建
1、C语言中动态内存分配(malloc)只在堆中分配一片内存,返回一个void指针(分配失败则返回0),并没有创建一个对象。使用时需要强制转换成恰当的类型。调用free则只负责释放一片内存,并没有析构一个对象。
2、创建一个C++对象,有两步:a 为对象分配内存;b 调用构造函数来初始化那片内存。
3、C++中把创建一个对象的所有动作都结合在一个称为new的运算符里。当用new创建一个对象时,它在堆里为对象分配内存并为这块内存调用构造函数。当分配内存失败时返回0。
4、运算符new分配内存是调用malloc实现的,在调用构造函数前,new会检查内存分配是否成功。
5、与new对应的则是delete,delete首先调用析构函数,然后释放内存(一般是调用free)。
6、如果delete的对象指针是0,将不发生任何事情,因此在删除一个对象后,应立即将其指针置0。因为重复删除同一对象会产生错误。
7、定义一个友元函数为内联函数不会改变友元状态,它依然是全局函数,而不是一个类的成员函数。
8、如果对一个void指针进行delete操作,唯一执行的是释放内存,而不会调用析构函数,因为void指针没有,类型信息用来确定调用哪个析构函数。
9、不要将在栈上创建的对象的指针和在堆上创建的对象的指针都放在同一个容器中,否则会产生严重的问题。
10、动态创建数组:new会调用默认的构造函数,delete需要“[]”来标识。
11、使指针更像数组:用如下方式:int* const arr = new int[10];,这里arr即为一个指针常量,其值不可修改,更像一个数组名。若为:int const* arr = new int[10]; 或 const int* arr = new int[10]; 这里的arr为一个常量指针,其指向的值不可修改。另外,数组名和指针的取值方式不一样:指针有两次取值才获得真正的对象,数组只需一次。
12、当new分配内存失败时,会调用new-handler函数,该函数默认产生一个bad_alloc的异常。
13、重载new和delete:重载new和delete时,我们只能改变原有的内存分配方法,因为我们无法控制构造函数和析构函数的调用。
继承与组合
1、在public继承中,派生类的对象也是基类的对象,但基类对象不是其派生类的对象;
2、将基类指针强制转换成派生类指针:derivedPtr = static_cast<baseClass*>(basePtr);
3、名字隐藏:a 在派生类中定义和基类中签名一样的函数,这叫普通成员函数重定义;如果基类中该函数是虚函数,则叫重写(overriding);b 如果签名不同,则基类中所有与该函数同名字的的函数在派生类中均自动隐藏了。
4、在覆盖定义基类成员函数时,调用基类中的该函数版本需用作用域运算符,否则实际调用的是该函数自身,会引起无穷递归。例:BaseClass::function();
5、继承类型:
a、public继承:基类的public成员成为派生类的public成员,protected成员成为派生类的protected成员,private成员则隐藏。
b、protected继承:基类的publ