1.static的作用
c语言:static修饰局部变量,延长生命周期,只初始化一次
static修饰全局变量,限制作用域,只在本文件中有效。
c++:static修饰成员变量,成员变量变成共享的,类内定义类外初始化,属于类,每一个对象都可以访问
static修饰成员函数,此成员函数变成共享函数,没有this指针,因此,静态成员函数不能访问非静态成员,非静态成员函数可以访问静态成员
2.const的作用
C语言:const修饰的变量只可读不可写
const int a;//栈区
指针常量:定义了一个指针,该指针被定义为常量,int *const p;指向不可以改变
常量指针:是一个指向常量的指针,int const *p;值不可以改变
C++:const修饰成员变量只能以列表的形式进行初始化,const修饰的成员变量只能读不可修改
const修饰成员函数不能访问非const修饰的成员函数
非const修饰的成员函数可以访问const修饰的成员
const修饰的类对象,只能访问const修饰的函数
3.多层继承
A->B->C
重定义:子类重定义父类的方法
4.多重继承(菱形继承)
人--->(工人,农民)继承--->(农民工)继承
问题:农民工会继承两份人的成员变量,从而引起二义性
解决:虚继承,工人和农民就会各自有一个虚基表指针,从而继承到农民工会有两个虚基表指针,就可以找到各自人的成员变量了。
5.多态
静态多态
重载
动态多态
将父类的对应函数写成虚函数,在子类中重写,通过父类对象的指针/引用去操作子类对象就可以调用到子类的函数了
什么时候有虚函数表? 一个类中一旦有了虚函数,那么这个类中就有了一个虚函数表,保存这个类中所有虚函数的地址,如果 这个类被子类继承了,子类中也会有一张虚函数表
父类和子类的虚函数表一样吗?
分情况: 如果子类没有重写父类的虚函数,那么父类和子类的虚函数表一样 如果子类重写了父类的虚函数,那么子类虚函数表就是子类重写之后对应的虚函数表,和父类的虚 函数表不一样
6.动态内存分配中遇到的问题
问题:把new出来的子类对象,赋值给父对象类型的指针,在整个操作工程中,都是通过父类的指针来操作,使用delete时,只执行了父类的析构函数,没有执行子类的析构函数,这种情况会造成内存泄露问题(如果在子类构造函数中new空间,而没有释放空间)
解决:将父类的析构函数写成虚函数,子类的析构函数也就变成了虚函数,有了虚基表指针就可以访问到子类的析构函数了
7.重载、重定义、重写的区别
重载:分为函数重载和运算符重载,函数重载是同一个作用域内,函数功能相似,函数名相同,参数不同(参数类型不同、参数个数不同、参数顺序不同),与返回值无关的一组函数
重定义:在继承关系中,子类重定义父类的方法,要求函数名相同即可
重写:在继承关系中,子类重写父类的虚函数,要求函数首部必须一样(返回值类型 函数名(形参列表)都必须一样)
8.内联函数
修饰类的成员函数,关键字:inline
inline 返回值类型 函数名(参数列表)
{
;
}
特点:代码量少 3-5行
频繁调用
逻辑简单
内联函数与宏函数的区别
宏函数是在预处理阶段,内联函数是在编译的时候处理
宏函数是直接替换,内联函数是把调用语句直接替换成函数体
9.单例模式
一个类只能创建一个对象
需求:《1》构造函数只能调用一次//打开数据库
《2》类内创建对象(静态成员变量)
《3》要访问这个对象(静态成员函数)
类的设计:
1.构造函数必须私有化
2.静态成员:保存唯一的对象
3.静态成员函数:获取唯一的对象
#include "sqlite3.h"
#include <iostream>
using namespace std;
class Mydata
{
public:
~Mydata();
static Mydata* getMydata();
private:
Mydata();
sqlite3 *db;
static Mydata*pData;//类内声明,类外初始化
};
懒汉模式
哪里需要。就在哪里创建
存在的问题:在多个线程中,多个线程都要获取这个单例对象
解决:线程锁
饿汉模式
不管是否使用,都准备好
Mydata* Mydata::pData = new Mydata;
存在的问题:占用资源
建议:一般使用懒汉模式