c语言中动态内存分配malloc只在堆中分配一片内存
、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(basePtr);
3、名字隐藏:a 在派生类中定义和基类中签名一样的函数,这叫普通成员函数重定义;如果基类中该函数是虚函数,则叫重写(overriding);b 如果签名不同,则基类中所有与该函数同名字的的函数在派生类中均自动隐藏了。
4、在覆盖定义基类成员函数时,调用基类中的该函数版本需用作用域运算符,否则实际调用的是该函数自身,会引起无穷递归。例:BaseClass::function();
5、继承类型:
a、public继承:基类的public成员成为派生类的public成员,protected成员成为派生类的protected成员,private成员则隐藏。
b、protected继承:基类的public成员和protected成员成为派生类的protected成员,private成员在派生类中不可见,隐藏。
c、private继承:基类的public成员和protected成员成为派生类的private成员,private成员在派生类中不可见,隐藏。
private和protected继承不是“is-a”(“是”)的关系。继承默认是private的。
6、类的构造是从类层次的最根处开始,而在每一层,首先会调用基类构造函数,然后调用成员对象构造函数。析构严格按照相反的顺序。注意:基类的构造在成员对象构造之前。构造函数调用的次序完全不受构造函数的初始化列表中次序的影响。
7、把派生类对象赋给基类对象,然后试图在该基类对象中引用只在派生类中才有的成员是个语法错误。
8、多重继承:用virtual继承时,派生类中只出现一个子对象,可解决重复子对象的问题。
9、java和C++的区别:java是纯粹的(pure)的面向对象语言,而C++ 是一种混合的(hybrid)语言。java是基于对象的继承层次结构模型,所有类都是在一个单一的继承层次结构中派生的,有一个基类为根(Object)。
10、非自动继承的函数:构造函数,析构函数,赋值函数(operator=)因为它完成类似于构造函数的功能。
11、静态成员函数不可以是虚函数。
12、将私有继承成员公有化:在派生类中的public部分声明其名字,例:
public:
using baseClass::membe