C++类知识点
C++三大特性
封装、继承、多态
封装
封装可以隐藏实现细节,使得代码模块化
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。
数据抽象
只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。
抽象类
类中至少有一个函数被声明为纯虚函数/纯虚函数是通过在声明中使用=0来指定。
抽象类不能被实例化。
多态
多态指的是父类类型的指针指向其子类对象,可以调用子类仲被重写的方法
动态联编、静态联编
动态联编: 在运行的时候,自动判断指向的成员函数
静态联编:在编译阶段,确定指向的成员函数是指针类型的成员函数
虚函数
虚函数的定义要遵循以下重要规则:
1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行滞后联编的。
2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。
3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。
4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。
5.构造函数不能是虚函数,因为构造的时候,对象还是一片位定型的空间,只有构造完成后,对象才是具体类的实例。
6.析构函数可以是虚函数,而且通常声名为虚函数。
static类数据成员/成员函数
两者都不能用this指针指向他们
- 类数据成员
static类数据成员独立于一切类对象存在。
static不会像普通类数据成员一样每一个类对象都有一份,全部类对象是共享一个static类成员的。
static类对象必须要在类外进行初始化
class Text{
public:
static int count;
} ;
int Text::count=0; //必须初始化
- 类成员函数
类成员函数里不能访问非static类成员
虚函数表vtable以及vptr
如果一个类包含了虚函数,那么在创建对象时会额外增加一张表,表中的每一项都是虚函数的入口地址,虚函数按照创建的优先顺序排列。这张表就是虚函数表,也称为 vtable。
可以认为虚函数表是一个数组。 为了把对象和虚函数表关联起来,编译器会在对象中安插一个指针vptr(在对象对应的内存空间的开头),指向虚函数表的起始位置。
例子:
class A{
protected:
int a1;
int a2;
public:
virtual void display(){
cout<<"A::display()"<<endl;
}
virtual void clone(){
cout<<"A::clone()"<<endl;
};
};
class B: public A{
protected:
int b;
public:
virtual void display(){
cout<<"B::display()"<<endl;
}
virtual void init(){
cout<<"B::init()"<<endl;
}
};
class C: public B{
protected:
int c;
public:
virtual void display(){
cout<<"C::display()"<<endl;
}
virtual void execute(){
cout<<"C::execute()"<<endl;
}
};
各个类的内存分布如下所示: