new: 为对象分配存储空间,调用了constructor函数;delete触发destructor函数执行;
destructor函数执行条件:
如果对象是自动变量,则退出定义对象的block时自动调用destructor函数
如果对象时静态变量,则程序终止时调用destructor函数
如果对象有new创建,只有直接调用delete才触发destructor函数调用
指针:
使用->操作符访问对象的成员函数;
对指针使用*操作符,获取对象本身;
char *buffer = new char[MAX_BUFFER];
String *pc1 = new (buffer) String(); //在buffer指向的buffer中分配内存;
placement new 创建的对象,析构时,对象指针直接调用析构函数完成delete工作;
pc1->~String();
转换函数:
c_name(type_name value);
operator type_name();
初始化队列:
类中非静态const成员或者引用成员必须使用初始化列表初始化,赋值操作不允许;
继承:
(:)符号指明某个class是基于另一个class; public继承表示基类的public成员将成为子类的公共成员;基类中private部分的
也将成为子类的一部分,但是只能通过public或protected函数访问
子类需要自身的constructor函数;实践中,子类调用父类的构造函数对基类private成员的初始化;
如果疏忽了基类对象的初始化,结果将如何?
首先,基类的成员先被创建,如果忘记调用基类构造函数,程序调用默认构造函数;
然后才是子类自身成员的初始化;
基类指针可以指向子类对象不需要进行类型cast操作;基类引用可以引用子类对象,这只是单向的,即基类到子类,
Is-a 关系:
特殊的基类和衍生类之间的关系是构建在C++继承模式之上。实际上,C++有三种不同模式的继承,分别是private, protected和public;
public模式最常用,它是一个Is-a关系,可认为衍生类对象应该是一个基类对象,任何可在基类对象的操作也可用于衍生类对象。
多态:
多态的底层支持机制:
在衍生类中重新定义基类函数
事应抽象函数
virtual关键字用于函数原型中,不用于定义;
在衍生类的覆写函数中中调用基类中同明函数,需要使用::操作符;
虚拟函数底层机制:
编译通常处理虚拟函数方式是在对象中新增一个隐藏成员,该成员引用一个函数地址数组(vtbl);数组中元素为定义的虚拟函数地址。
1、关键字virtual将函数声明为虚拟函数,同时也使得在衍生类中也是虚拟函数;
2、虚拟函数触发调用通过引用或指针;
对象类型和变量类型;
1:构造函数不能声明为虚拟化
2:析构函数必须声明为虚拟函数,除非不用于继承;
3、友元不能为虚拟函数
4、如果衍生类未重新定义函数,则使用基类中的版本;
5、衍生类中重定义的同名虚拟函数覆盖基类的虚拟函数;
基础抽象类:
类声明中包含纯虚函数,不能创建此类的对象。
纯虚函数定义
abstract type func() = 0;
基类中虚拟destructor的作用?
如果基类中destructor非虚拟,则指针所属类型的destructor被调用,即使指针指向衍生类对象;虚拟destructor确保正确的destructor
被调用。
调用衍生类destructor时,自动调用基类的destructor;
静态绑定:绑定发生在编译的时候;
动态绑定:程序运行时发生的绑定;由指针或者引用引起的函数调用;涉及虚拟函数;
两种绑定出现的原因是效率和概念模型。
upcasting:衍生类引用或指针转换为基类引用或指针的过程,隐式的转换;
函数参数类型为基类引用或指针,
void fr(BaseClass &br);
void fp(BaseClass *bp);
void fv(BaseClass b); //
downcasting: 方向同upcasting相反,需要直接类型转换;
overload:重载,函数名相同,参数类型或格式不同。
override:
Has-a
Use-a
Is-implemented-as-a
class Rating : public TableTenniesPlayer {
private:
double rating;
public:
Rating(const string &fn, const string &ln, const double rating);
}
Rating::Rating(const string &fn, const string &ln, const double r) : TableTenniesPlayer(fn, ln) {
rating = r;
}